diff -Nru openjdk-lts-11.0.20.1+1/debian/changelog openjdk-lts-11.0.21+9/debian/changelog --- openjdk-lts-11.0.20.1+1/debian/changelog 2023-08-24 22:33:45.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/changelog 2023-10-19 07:54:46.000000000 +0000 @@ -1,18 +1,30 @@ -openjdk-lts (11.0.20.1+1-0ubuntu1~23.04) lunar-security; urgency=medium +openjdk-lts (11.0.21+9-0ubuntu1~23.04) lunar-security; urgency=medium - * Upload to Ubuntu 23.04. - - -- Vladimir Petko Fri, 25 Aug 2023 10:33:45 +1200 + * OpenJDK 11.0.21 release, build 9. + - CVE-2023-22081. + - Release notes: + https://mail.openjdk.org/pipermail/jdk-updates-dev/2023-October/026351.html + * d/source/lintian.overrides: use openjdk-lts package name. + * Merge changes from openjdk-11 11.0.21+9-1 (LP: #2039754). + - d/test: update problemlist. + - d/p: drop exclude-broken-tests.patch. + - d/p/reproducible-properties-timestamp.diff: use the privileged action + to read the system property (JDK-8272157, 914278). + - d/copyright: remove liblcms from excluded files. + - d/t/jtreg-autopkgtest.{sh,in}: JDK-8232153 - set NSS_DEFAULT_DB_TYPE + to let sun/security/pkcs11/Secmod/AddTrustedCert.java pass. + + [ Matthias Klose ] + - Build using GCC 13 on development versions. + - Explicitly configure --without-jtreg with the nocheck profile -openjdk-lts (11.0.20.1+1-0ubuntu1) mantic; urgency=medium + [ Pushkar Kulkarni ] + - Handle limited ECC capabilities of NSS on older releases. - * OpenJDK 11.0.20.1 release, build 1. - - REGRESSION UPDATE: 8313765: Invalid CEN header (invalid zip64 extra data - field size) (LP: #2032865). - * d/t/jtreg-autopkgtest.{sh,in}: JDK-8232153 - set NSS_DEFAULT_DB_TYPE - to let sun/security/pkcs11/Secmod/AddTrustedCert.java pass. + [ Vladimir Petko ] + * Upload to Ubuntu 23.04. - -- Vladimir Petko Thu, 24 Aug 2023 11:22:16 +1200 + -- Vladimir Petko Thu, 19 Oct 2023 20:54:46 +1300 openjdk-lts (11.0.20+8-1ubuntu1) mantic; urgency=high diff -Nru openjdk-lts-11.0.20.1+1/debian/copyright openjdk-lts-11.0.21+9/debian/copyright --- openjdk-lts-11.0.20.1+1/debian/copyright 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/copyright 2023-10-19 02:48:32.000000000 +0000 @@ -2,8 +2,6 @@ Files-Excluded: .github/* .gitattributes - src/java.desktop/share/native/liblcms/cms*.c - src/java.desktop/share/native/liblcms/lcms2*.h src/java.base/share/native/libzip/zlib/* src/java.desktop/share/native/libsplashscreen/giflib/* src/java.desktop/share/native/libsplashscreen/libpng/* diff -Nru openjdk-lts-11.0.20.1+1/debian/patches/exclude-broken-tests.patch openjdk-lts-11.0.21+9/debian/patches/exclude-broken-tests.patch --- openjdk-lts-11.0.20.1+1/debian/patches/exclude-broken-tests.patch 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/patches/exclude-broken-tests.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ - Description: Disable failing tests - Disable tests that fail on Ubuntu pending investigation -Author: Vladimir Petko -Forwarded: not-needed -Last-Update: 2023-03-24 ---- a/test/hotspot/jtreg/ProblemList.txt -+++ b/test/hotspot/jtreg/ProblemList.txt -@@ -38,6 +38,26 @@ - # - ############################################################################# - -+# tests that need to be investigated -+ -+gc/shenandoah/mxbeans/TestChurnNotifications.java#aggressive 0000000 generic-all -+gc/shenandoah/mxbeans/TestChurnNotifications.java#iu 0000000 generic-all -+ -+#result: Failed. Execution failed: `main' threw exception: java.io.IOException: Mount point not found -+# https://bugs.openjdk.org/browse/JDK-8166162 -+ -+runtime/LoadClass/LongBCP.java 8166162 generic-all -+ -+# Intermittent failures because LingeredApp.class is not found -+ -+runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java 000000 generic-all -+runtime/cds/appcds/jcmd/JCmdTestFileSafety.java 000000 generic-all -+runtime/cds/appcds/jcmd/JCmdTestStaticDump.java 000000 generic-all -+ -+# Unexpected exit from the test -+ -+runtime/NMT/SafepointPollingPages.java 000000 generic-all -+ - # :hotspot_compiler - - compiler/aot/verification/vmflags/TrackedFlagTest.java 8215224 generic-all ---- a/test/langtools/ProblemList.txt -+++ b/test/langtools/ProblemList.txt -@@ -23,6 +23,32 @@ - # - ########################################################################### - -+# Wrong test environment in autopkgtest -+# java.lang.IllegalStateException: Launching JShell execution engine threw: ERROR: transport error 202: getaddrinfo: failed to parse address -+ -+jdk/jshell/JdiListeningLocalhostExecutionControlTest.java 0000000 generic-all -+ -+# tests failing due to disable-doclint-by-default.diff -+ -+jdk/javadoc/doclet/testSupplementary/TestSupplementary.java 0000000 generic-all -+jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java 0000000 generic-all -+jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java 0000000 generic-all -+jdk/javadoc/doclet/testStylesheet/TestStylesheet.java 0000000 generic-all -+jdk/javadoc/doclet/testSeeTag/TestSeeTag.java 0000000 generic-all -+jdk/javadoc/doclet/testRelativeLinks/TestRelativeLinks.java 0000000 generic-all -+jdk/javadoc/doclet/testBadHtml/TestBadHtml.java 0000000 generic-all -+jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java 0000000 generic-all -+jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java 0000000 generic-all -+jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java 0000000 generic-all -+jdk/javadoc/doclet/testLinkOption/TestLinkOption.java 0000000 generic-all -+jdk/javadoc/doclet/T6735320/T6735320.java 0000000 generic-all -+jdk/javadoc/doclet/testValueTag/TestValueTag.java 0000000 generic-all -+jdk/javadoc/tool/modules/Modules.java 0000000 generic-all -+jdk/javadoc/doclet/testWarnings/TestWarnings.java 0000000 generic-all -+jdk/javadoc/doclet/testHtmlTableStyles/TestHtmlTableStyles.java 0000000 generic-all -+jdk/javadoc/tool/doclint/DocLintTest.java 0000000 generic-all -+jdk/javadoc/doclet/testBadPackageFileInJar/TestBadPackageFileInJar.java 0000000 generic-all -+ - ########################################################################### - # - # javadoc ---- a/test/jdk/ProblemList.txt -+++ b/test/jdk/ProblemList.txt -@@ -110,6 +110,49 @@ - # - ############################################################################# - -+ -+ -+# to investigate -+# unable to read LD_LIBRARY_PATH env variable -+ -+tools/jpackage/share/AppLauncherEnvTest.java 0000000 generic-all -+ -+# java.lang.Exception: Proc abnormal end -+ -+sun/security/krb5/auto/Cleaners.java 0000000 generic-all -+ -+# result: Failed. Execution failed: `main' threw exception: java.io.IOException: Mount point not found -+# https://bugs.openjdk.org/browse/JDK-8166162 -+ -+java/io/File/createTempFile/TargetDirectory.java 8166162 generic-all -+java/nio/file/Files/CheckPermissions.java 8166162 generic-all -+java/nio/file/Files/TemporaryFiles.java 8166162 generic-all -+java/nio/file/Files/Misc.java 8166162 generic-all -+java/nio/file/Files/CopyAndMove.java 8166162 generic-all -+java/nio/file/Files/InterruptCopy.java 8166162 generic-all -+java/nio/file/Files/FileAttributes.java 8166162 generic-all -+java/nio/file/attribute/BasicFileAttributeView/SetTimesNanos.java 8166162 generic-all -+java/nio/file/attribute/AclFileAttributeView/Basic.java 8166162 generic-all -+java/nio/file/attribute/DosFileAttributeView/Basic.java 8166162 generic-all -+java/nio/file/attribute/PosixFileAttributeView/Basic.java 8166162 generic-all -+java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java 8166162 generic-all -+java/nio/file/FileStore/Basic.java 8166162 generic-all -+java/nio/channels/FileChannel/directio/DirectIOTest.java 8166162 generic-all -+java/nio/channels/FileChannel/directio/ReadDirect.java 8166162 generic-all -+java/nio/channels/FileChannel/directio/PreadDirect.java 8166162 generic-all -+java/nio/channels/FileChannel/directio/PwriteDirect.java 8166162 generic-all -+java/nio/channels/FileChannel/directio/WriteDirect.java 8166162 generic-all -+ -+# utf-8 locale is missing on build machine -+# https://bugs.openjdk.org/browse/JDK-8249079 -+ -+java/lang/invoke/lambda/LambdaFileEncodingSerialization.java 8249079 generic-all -+ -+# reproducible-properties-timestamp.diff introduce a bug that breaks this test -+# remove after the patch is dropped -+ -+java/util/logging/LogManager/Configuration/updateConfiguration/SimpleUpdateConfigWithInputStreamTest.java 000000 generic-all -+ - ############################################################################ - - # jdk_awt diff -Nru openjdk-lts-11.0.20.1+1/debian/patches/nss-limited-ecc-tests.patch openjdk-lts-11.0.21+9/debian/patches/nss-limited-ecc-tests.patch --- openjdk-lts-11.0.20.1+1/debian/patches/nss-limited-ecc-tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/patches/nss-limited-ecc-tests.patch 2023-10-19 02:48:32.000000000 +0000 @@ -0,0 +1,48 @@ +--- a/test/jdk/sun/security/pkcs11/PKCS11Test.java ++++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java +@@ -99,7 +99,7 @@ + // NSS version info + public static enum ECCState { None, Basic, Extended }; + static double nss_version = -1; +- static ECCState nss_ecc_status = ECCState.Extended; ++ static ECCState nss_ecc_status = ECCState.Basic; + + // The NSS library we need to search for in getNSSLibDir() + // Default is "libsoftokn3.so", listed as "softokn3" +--- a/test/jdk/sun/security/pkcs11/ec/TestECDH.java ++++ b/test/jdk/sun/security/pkcs11/ec/TestECDH.java +@@ -124,8 +124,12 @@ + return; + } + +- test(p, pub192a, priv192a, pub192b, priv192b, secret192); +- test(p, pub163a, priv163a, pub163b, priv163b, secret163); ++ if (getSupportedECParameterSpec("secp192r1", p).isPresent()) { ++ test(p, pub192a, priv192a, pub192b, priv192b, secret192); ++ } ++ if (getSupportedECParameterSpec("sect163r1", p).isPresent()) { ++ test(p, pub163a, priv163a, pub163b, priv163b, secret163); ++ } + + if (getSupportedECParameterSpec("brainpoolP256r1", p).isPresent()) { + test(p, pubBrainpoolP256r1a, privBrainpoolP256r1a, pubBrainpoolP256r1b, privBrainpoolP256r1b, secretBrainpoolP256r1); +--- a/test/jdk/sun/security/pkcs11/ec/TestECDSA.java ++++ b/test/jdk/sun/security/pkcs11/ec/TestECDSA.java +@@ -156,12 +156,14 @@ + return; + } + +- if (getNSSECC() != ECCState.Basic) { ++ if (getSupportedECParameterSpec("secp192r1", provider).isPresent()) { + test(provider, pub192, priv192, sig192); ++ } ++ if (getSupportedECParameterSpec("sect163r1", provider).isPresent()) { + test(provider, pub163, priv163, sig163); ++ } ++ if (getSupportedECParameterSpec("sect571r1", provider).isPresent()) { + test(provider, pub571, priv571, sig571); +- } else { +- System.out.println("ECC Basic only, skipping 192, 163 and 571."); + } + test(provider, pub521, priv521, sig521); + diff -Nru openjdk-lts-11.0.20.1+1/debian/patches/reproducible-properties-timestamp.diff openjdk-lts-11.0.21+9/debian/patches/reproducible-properties-timestamp.diff --- openjdk-lts-11.0.20.1+1/debian/patches/reproducible-properties-timestamp.diff 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/patches/reproducible-properties-timestamp.diff 2023-10-19 02:48:32.000000000 +0000 @@ -3,7 +3,17 @@ Forwarded: no --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java -@@ -929,7 +929,7 @@ +@@ -53,6 +53,9 @@ + import sun.nio.cs.UTF_8; + import sun.nio.cs.ISO_8859_1; + ++import java.security.AccessController; ++import java.security.PrivilegedAction; ++ + /** + * The {@code Properties} class represents a persistent set of + * properties. The {@code Properties} can be saved to a stream +@@ -929,7 +932,7 @@ if (comments != null) { writeComments(bw, comments); } @@ -12,7 +22,7 @@ bw.newLine(); synchronized (this) { for (Map.Entry e : entrySet()) { -@@ -1579,4 +1579,22 @@ +@@ -1579,4 +1582,27 @@ } this.map = map; } @@ -23,14 +33,19 @@ + * environment variable is specified. In this case the format used is + * locale and timezone insensitive to ensure the output is reproducible. + */ ++ @SuppressWarnings("removal") + private String getFormattedTimestamp() { -+ if (System.getenv("SOURCE_DATE_EPOCH") == null) { ++ String epoch = AccessController.doPrivileged(new PrivilegedAction(){ ++ public String run() { return System.getenv("SOURCE_DATE_EPOCH"); } ++ }); ++ ++ if (epoch == null) { + return new Date().toString(); + } else { + // Use the SOURCE_DATE_EPOCH timestamp and make the format locale/timezone insensitive + java.text.SimpleDateFormat fmt = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss z", java.util.Locale.ENGLISH); + fmt.setTimeZone(java.util.TimeZone.getTimeZone("UTC")); -+ Date date = new Date(1000 * Long.parseLong(System.getenv("SOURCE_DATE_EPOCH"))); ++ Date date = new Date(1000 * Long.parseLong(epoch)); + return fmt.format(date); + } + } diff -Nru openjdk-lts-11.0.20.1+1/debian/patches/series openjdk-lts-11.0.21+9/debian/patches/series --- openjdk-lts-11.0.20.1+1/debian/patches/series 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/patches/series 2023-10-19 02:48:32.000000000 +0000 @@ -38,4 +38,4 @@ update-permission-test.patch ldap-timeout-test-use-ip.patch test-use-ip-address.patch -exclude-broken-tests.patch +nss-limited-ecc-tests.patch diff -Nru openjdk-lts-11.0.20.1+1/debian/rules openjdk-lts-11.0.21+9/debian/rules --- openjdk-lts-11.0.20.1+1/debian/rules 2023-08-24 22:33:43.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/rules 2023-10-19 07:54:45.000000000 +0000 @@ -78,6 +78,7 @@ endif is_upstream_release = yes +#is_upstream_release = srcdir = . builddir = build @@ -335,10 +336,14 @@ export CC = $(DEB_HOST_GNU_TYPE)-gcc-11 export CXX = $(DEB_HOST_GNU_TYPE)-g++-11 bd_gcc = g++-11 , -else +else ifneq (,$(filter $(distrel),bookworm lunar)) export CC = $(DEB_HOST_GNU_TYPE)-gcc-12 export CXX = $(DEB_HOST_GNU_TYPE)-g++-12 bd_gcc = g++-12 , +else + export CC = $(DEB_HOST_GNU_TYPE)-gcc-13 + export CXX = $(DEB_HOST_GNU_TYPE)-g++-13 + bd_gcc = g++-13 , endif # until we are able to b-d on gcc-for-host ... @@ -1878,8 +1883,9 @@ dh_builddeb -a $(nodemo) $(nojrez) #$(bd_options) is_release = yes +#is_release = git_project = jdk11u -git_tag = jdk-11.0.20+8 +git_tag = jdk-11.0.21+9 package_version = $(subst jdk-,,$(git_tag)) package_version = $(shell echo $(PKGVERSION) | sed 's/-[^-][^-]*$$//') ifneq ($(is_release),yes) diff -Nru openjdk-lts-11.0.20.1+1/debian/source/lintian-overrides openjdk-lts-11.0.21+9/debian/source/lintian-overrides --- openjdk-lts-11.0.20.1+1/debian/source/lintian-overrides 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/source/lintian-overrides 2023-10-19 03:13:49.000000000 +0000 @@ -1,2 +1,2 @@ # parts of the test suite, not installed -openjdk-11 source: source-is-missing +openjdk-lts source: source-is-missing diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/hotspot openjdk-lts-11.0.21+9/debian/tests/hotspot --- openjdk-lts-11.0.20.1+1/debian/tests/hotspot 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/hotspot 2023-10-19 02:48:32.000000000 +0000 @@ -4,13 +4,8 @@ set -o pipefail set -o nounset -problem_list=${AUTOPKGTEST_TMP}/hotspot-problems.txt -cat test/hotspot/jtreg/ProblemList.txt > ${problem_list} - -host_arch="${DEB_HOST_ARCH:-$(dpkg --print-architecture)}" -if [[ -f debian/tests/problems-${host_arch}.txt ]]; then - cat debian/tests/problems-${host_arch}.txt >> ${problem_list} -fi +problem_list=${AUTOPKGTEST_TMP}/problems.txt +debian/tests/write-problems ${problem_list} test/hotspot/jtreg/ProblemList.txt hotspot native_path=$(pwd)/build/images/test/hotspot/jtreg/native debian/tests/jtreg-autopkgtest.sh hotspot \ diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/jaxp openjdk-lts-11.0.21+9/debian/tests/jaxp --- openjdk-lts-11.0.20.1+1/debian/tests/jaxp 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/jaxp 2023-10-19 02:48:32.000000000 +0000 @@ -4,10 +4,12 @@ set -o pipefail set -o nounset +problem_list=${AUTOPKGTEST_TMP}/problems.txt +debian/tests/write-problems ${problem_list} test/jaxp/ProblemList.txt jaxp + debian/tests/jtreg-autopkgtest.sh jaxp \ - -exclude:test/jaxp/ProblemList.txt \ + -exclude:${problem_list} \ -dir:test/jaxp \ -k:!stress \ :tier1 :tier2 - debian/tests/jtdiff-autopkgtest.sh jaxp diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/jdk openjdk-lts-11.0.21+9/debian/tests/jdk --- openjdk-lts-11.0.20.1+1/debian/tests/jdk 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/jdk 2023-10-19 02:48:32.000000000 +0000 @@ -4,6 +4,7 @@ set -o pipefail set -o nounset + cleanup() { # kill window manager to clean up (rest will exit automatically) pid="$(jobs -p)" @@ -25,13 +26,8 @@ debian/tests/start-xvfb.sh 10 & sleep 3 -problem_list=${AUTOPKGTEST_TMP}/jdk-problems.txt -cat test/jdk/ProblemList.txt > ${problem_list} - -host_arch="${DEB_HOST_ARCH:-$(dpkg --print-architecture)}" -if [[ -f debian/tests/problems-${host_arch}.txt ]]; then - cat debian/tests/problems-${host_arch}.txt >> ${problem_list} -fi +problem_list=${AUTOPKGTEST_TMP}/problems.txt +debian/tests/write-problems ${problem_list} test/jdk/ProblemList.txt jdk native_path=$(pwd)/build/images/test/jdk/jtreg/native debian/tests/jtreg-autopkgtest.sh jdk \ diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/jtreg-autopkgtest.in openjdk-lts-11.0.21+9/debian/tests/jtreg-autopkgtest.in --- openjdk-lts-11.0.20.1+1/debian/tests/jtreg-autopkgtest.in 2023-08-24 03:39:40.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/jtreg-autopkgtest.in 2023-10-19 02:48:32.000000000 +0000 @@ -32,7 +32,7 @@ if dpkg --compare-versions ${jtreg_version} ge 4.2; then jt_options+=" -conc:auto" fi - + # check java binary if [ ! -x "${JDK_TO_TEST}/bin/java" ]; then echo "Error: '${JDK_TO_TEST}/bin/java' is not an executable." >&2 @@ -104,6 +104,8 @@ -jdk:${JDK_TO_TEST} \ -vmoption:-Dtest.boot.jdk=${BOOTJDK_HOME} \ -vmoption:-XX:MaxRAMPercentage=25 \ + -vmoption:-Duser.home=${AUTOPKGTEST_TMP} \ + -vmoption:-Djava.io.tmpdir=${AUTOPKGTEST_TMP} \ -e:NSS_DEFAULT_DB_TYPE=sql \ ${on_retry:-} $@ \ && exit_code=0 || exit_code=$? diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/jtreg-autopkgtest.sh openjdk-lts-11.0.21+9/debian/tests/jtreg-autopkgtest.sh --- openjdk-lts-11.0.20.1+1/debian/tests/jtreg-autopkgtest.sh 2023-08-24 03:39:40.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/jtreg-autopkgtest.sh 2023-10-19 02:48:32.000000000 +0000 @@ -109,6 +109,8 @@ -reportDir:"${report_dir}" \ -jdk:${JDK_TO_TEST} \ -vmoption:-Dtest.boot.jdk=${BOOTJDK_HOME} \ + -vmoption:-Duser.home=${AUTOPKGTEST_TMP} \ + -vmoption:-Djava.io.tmpdir=${AUTOPKGTEST_TMP} \ -vmoption:-XX:MaxRAMPercentage=25 \ -e:NSS_DEFAULT_DB_TYPE=sql \ ${on_retry:-} $@ \ diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/langtools openjdk-lts-11.0.21+9/debian/tests/langtools --- openjdk-lts-11.0.20.1+1/debian/tests/langtools 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/langtools 2023-10-19 02:48:32.000000000 +0000 @@ -4,10 +4,12 @@ set -o pipefail set -o nounset +problem_list=${AUTOPKGTEST_TMP}/problems.txt +debian/tests/write-problems ${problem_list} test/langtools/ProblemList.txt langtools + debian/tests/jtreg-autopkgtest.sh langtools \ - -exclude:test/langtools/ProblemList.txt \ - -dir:test/langtools \ + -exclude:${problem_list} \ + -dir:test/langtools \ -k:!stress \ :tier1 :tier2 - debian/tests/jtdiff-autopkgtest.sh langtools diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/problems-armhf.txt openjdk-lts-11.0.21+9/debian/tests/problems-armhf.txt --- openjdk-lts-11.0.20.1+1/debian/tests/problems-armhf.txt 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/problems-armhf.txt 2023-10-19 02:48:32.000000000 +0000 @@ -18,5 +18,20 @@ # this test passes but is very slow in CI, causing timeout jdk/sun/security/rsa/SignedObjectChain.java 000000 generic-all +sun/security/rsa/SignedObjectChain.java 000000 generic-all sun/security/ec/ed/EdDSATest.java 000000 generic-all -java/security/SignedObject/Chain.java 000000 generic-all \ No newline at end of file +java/security/SignedObject/Chain.java 000000 generic-all + +# timeout in SSL connection +java/net/httpclient/ManyRequestsLegacy.java 000000 generic-all +# deadlock +java/util/Random/RandomTestBsi1999.java 000000 generic-all + +# runner issue, disk space size exceeds 32 bit integer +java/io/File/GetXSpace.java 000000 generic-all + +# https://bugs.openjdk.org/browse/JDK-8303168 +serviceability/AsyncGetCallTrace/MyPackage/ASGCTBaseTest.java 000000 generic-all + +# native stack not implemented +runtime/jni/nativeStack/TestNativeStack.java 000000 generic-all diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/problems-hotspot.txt openjdk-lts-11.0.21+9/debian/tests/problems-hotspot.txt --- openjdk-lts-11.0.20.1+1/debian/tests/problems-hotspot.txt 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/problems-hotspot.txt 2023-10-19 02:48:32.000000000 +0000 @@ -0,0 +1,21 @@ +# tests that need to be investigated + +gc/shenandoah/mxbeans/TestChurnNotifications.java#aggressive 0000000 generic-all +gc/shenandoah/mxbeans/TestChurnNotifications.java#iu 0000000 generic-all + +#result: Failed. Execution failed: `main' threw exception: java.io.IOException: Mount point not found +# https://bugs.openjdk.org/browse/JDK-8166162 + +runtime/LoadClass/LongBCP.java 8166162 generic-all + +# flaky test +compiler/vectorization/runner/MultipleLoopsTest.java 000000 generic-all + +# Intermittent failures because LingeredApp.class is not found +runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java 000000 generic-all +runtime/cds/appcds/jcmd/JCmdTestFileSafety.java 000000 generic-all +runtime/cds/appcds/jcmd/JCmdTestStaticDump.java 000000 generic-all + +# Unexpected exit from the test +runtime/NMT/SafepointPollingPages.java 000000 generic-all + diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/problems-i386.txt openjdk-lts-11.0.21+9/debian/tests/problems-i386.txt --- openjdk-lts-11.0.20.1+1/debian/tests/problems-i386.txt 2023-08-23 23:18:58.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/problems-i386.txt 2023-10-19 02:48:32.000000000 +0000 @@ -13,3 +13,6 @@ tools/jlink/JLinkTest.java 000000 generic-all java/net/httpclient/http2/HpackBinaryTestDriver.java 000000 generic-all + +# runner issue, disk space size exceeds 32 bit integer +java/io/File/GetXSpace.java 000000 generic-all diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/problems-jdk.txt openjdk-lts-11.0.21+9/debian/tests/problems-jdk.txt --- openjdk-lts-11.0.20.1+1/debian/tests/problems-jdk.txt 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/problems-jdk.txt 2023-10-19 02:48:32.000000000 +0000 @@ -0,0 +1,45 @@ +# NSS3 failure when processing SHA3 hashes (needs investigation) +sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java 0000000 generic-all +sun/security/pkcs11/MessageDigest/TestCloning.java 0000000 generic-all +sun/security/pkcs11/Signature/SignatureTestPSS.java 0000000 generic-all + +# https://bugs.openjdk.org/browse/JDK-8312488 +tools/jpackage/share/AppLauncherEnvTest.java 0000000 generic-all + +# java.lang.Exception: Proc abnormal end +sun/security/krb5/auto/Cleaners.java 0000000 generic-all + +# result: Failed. Execution failed: `main' threw exception: java.io.IOException: Mount point not found +# https://bugs.openjdk.org/browse/JDK-8166162 + +java/io/File/createTempFile/TargetDirectory.java 8166162 generic-all +java/nio/file/Files/CheckPermissions.java 8166162 generic-all +java/nio/file/Files/TemporaryFiles.java 8166162 generic-all +java/nio/file/Files/Misc.java 8166162 generic-all +java/nio/file/Files/CopyAndMove.java 8166162 generic-all +java/nio/file/Files/InterruptCopy.java 8166162 generic-all +java/nio/file/Files/FileAttributes.java 8166162 generic-all +java/nio/file/attribute/BasicFileAttributeView/SetTimesNanos.java 8166162 generic-all +java/nio/file/attribute/AclFileAttributeView/Basic.java 8166162 generic-all +java/nio/file/attribute/DosFileAttributeView/Basic.java 8166162 generic-all +java/nio/file/attribute/PosixFileAttributeView/Basic.java 8166162 generic-all +java/nio/file/attribute/UserDefinedFileAttributeView/Basic.java 8166162 generic-all +java/nio/file/FileStore/Basic.java 8166162 generic-all +java/nio/channels/FileChannel/directio/DirectIOTest.java 8166162 generic-all +java/nio/channels/FileChannel/directio/ReadDirect.java 8166162 generic-all +java/nio/channels/FileChannel/directio/PreadDirect.java 8166162 generic-all +java/nio/channels/FileChannel/directio/PwriteDirect.java 8166162 generic-all +java/nio/channels/FileChannel/directio/WriteDirect.java 8166162 generic-all + +# utf-8 locale is missing on build machine +# https://bugs.openjdk.org/browse/JDK-8249079 + +java/lang/invoke/lambda/LambdaFileEncodingSerialization.java 8249079 generic-all + +# disable scoped value (incubating feature) test pending investigation + +jdk/incubator/concurrent/ScopedValue/StressStackOverflow.java 000000 generic-all +java/lang/ScopedValue/StressStackOverflow.java 000000 generic-all + +# https://bugs.openjdk.org/browse/JDK-8309214 +sun/security/pkcs11/KeyStore/CertChainRemoval.java 000000 generic-all diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/problems-langtools.txt openjdk-lts-11.0.21+9/debian/tests/problems-langtools.txt --- openjdk-lts-11.0.20.1+1/debian/tests/problems-langtools.txt 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/problems-langtools.txt 2023-10-19 02:48:32.000000000 +0000 @@ -0,0 +1,24 @@ +# Wrong test environment in autopkgtest +# java.lang.IllegalStateException: Launching JShell execution engine threw: ERROR: transport error 202: getaddrinfo: failed to parse address +jdk/jshell/JdiListeningLocalhostExecutionControlTest.java 0000000 generic-all + +# tests failing due to disable-doclint-by-default.diff + +jdk/javadoc/doclet/testSupplementary/TestSupplementary.java 0000000 generic-all +jdk/javadoc/doclet/testPackageHtml/TestPackageHtml.java 0000000 generic-all +jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java 0000000 generic-all +jdk/javadoc/doclet/testStylesheet/TestStylesheet.java 0000000 generic-all +jdk/javadoc/doclet/testSeeTag/TestSeeTag.java 0000000 generic-all +jdk/javadoc/doclet/testRelativeLinks/TestRelativeLinks.java 0000000 generic-all +jdk/javadoc/doclet/testBadHtml/TestBadHtml.java 0000000 generic-all +jdk/javadoc/doclet/testParamTaglet/TestParamTaglet.java 0000000 generic-all +jdk/javadoc/doclet/testNonInlineHtmlTagRemoval/TestNonInlineHtmlTagRemoval.java 0000000 generic-all +jdk/javadoc/doclet/dupThrowsTags/TestDupThrowsTags.java 0000000 generic-all +jdk/javadoc/doclet/testLinkOption/TestLinkOption.java 0000000 generic-all +jdk/javadoc/doclet/T6735320/T6735320.java 0000000 generic-all +jdk/javadoc/doclet/testValueTag/TestValueTag.java 0000000 generic-all +jdk/javadoc/tool/modules/Modules.java 0000000 generic-all +jdk/javadoc/doclet/testWarnings/TestWarnings.java 0000000 generic-all +jdk/javadoc/doclet/testHtmlTableStyles/TestHtmlTableStyles.java 0000000 generic-all +jdk/javadoc/tool/doclint/DocLintTest.java 0000000 generic-all +jdk/javadoc/doclet/testBadPackageFileInJar/TestBadPackageFileInJar.java 0000000 generic-all diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/problems-s390x.txt openjdk-lts-11.0.21+9/debian/tests/problems-s390x.txt --- openjdk-lts-11.0.20.1+1/debian/tests/problems-s390x.txt 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/problems-s390x.txt 2023-10-19 02:48:32.000000000 +0000 @@ -0,0 +1,3 @@ +# https://bugs.openjdk.org/browse/JDK-8309698 +runtime/NMT/VirtualAllocCommitMerge.java 000000 generic-all + diff -Nru openjdk-lts-11.0.20.1+1/debian/tests/write-problems openjdk-lts-11.0.21+9/debian/tests/write-problems --- openjdk-lts-11.0.20.1+1/debian/tests/write-problems 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/debian/tests/write-problems 2023-10-19 02:48:32.000000000 +0000 @@ -0,0 +1,25 @@ +#!/bin/bash + +problem_list=$1 +upstream_problems=$2 +suite=$3 + +cat ${upstream_problems} > ${problem_list} + +if [[ -f debian/tests/problems-${suite}.txt ]]; then + cat debian/tests/problems-${suite}.txt >> ${problem_list} +fi + +distrel=`lsb_release --codename --short` +if [[ -f debian/tests/problems-${distrel}.txt ]]; then + cat debian/tests/problems-${distrel}.txt >> ${problem_list} +fi + +host_arch="${DEB_HOST_ARCH:-$(dpkg --print-architecture)}" +if [[ -f debian/tests/problems-${host_arch}.txt ]]; then + cat debian/tests/problems-${host_arch}.txt >> ${problem_list} +fi + +if [[ -f debian/tests/problems-${distrel}-${host_arch}.txt ]]; then + cat debian/tests/problems-${distrel}-${host_arch}.txt >> ${problem_list} +fi diff -Nru openjdk-lts-11.0.20.1+1/.jcheck/conf openjdk-lts-11.0.21+9/.jcheck/conf --- openjdk-lts-11.0.20.1+1/.jcheck/conf 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/.jcheck/conf 2023-10-06 05:33:33.000000000 +0000 @@ -1,7 +1,7 @@ [general] project=jdk-updates jbs=JDK -version=11.0.20.1 +version=11.0.21 [checks] error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace diff -Nru openjdk-lts-11.0.20.1+1/make/autoconf/hotspot.m4 openjdk-lts-11.0.21+9/make/autoconf/hotspot.m4 --- openjdk-lts-11.0.20.1+1/make/autoconf/hotspot.m4 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/autoconf/hotspot.m4 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. # 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,8 +165,11 @@ DTRACE_DEP_MISSING=false - AC_MSG_CHECKING([for dtrace tool]) - if test "x$DTRACE" != "x" && test -x "$DTRACE"; then + AC_MSG_CHECKING([for dtrace tool and platform support]) + if test "x$OPENJDK_TARGET_CPU_ARCH" = "xppc"; then + AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU_ARCH]) + DTRACE_DEP_MISSING=true + elif test "x$DTRACE" != "x" && test -x "$DTRACE"; then AC_MSG_RESULT([$DTRACE]) else AC_MSG_RESULT([not found, cannot build dtrace]) diff -Nru openjdk-lts-11.0.20.1+1/make/autoconf/version-numbers openjdk-lts-11.0.21+9/make/autoconf/version-numbers --- openjdk-lts-11.0.20.1+1/make/autoconf/version-numbers 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/autoconf/version-numbers 2023-10-06 05:33:33.000000000 +0000 @@ -28,12 +28,12 @@ DEFAULT_VERSION_FEATURE=11 DEFAULT_VERSION_INTERIM=0 -DEFAULT_VERSION_UPDATE=20 -DEFAULT_VERSION_PATCH=1 +DEFAULT_VERSION_UPDATE=21 +DEFAULT_VERSION_PATCH=0 DEFAULT_VERSION_EXTRA1=0 DEFAULT_VERSION_EXTRA2=0 DEFAULT_VERSION_EXTRA3=0 -DEFAULT_VERSION_DATE=2023-08-24 +DEFAULT_VERSION_DATE=2023-10-17 DEFAULT_VERSION_CLASSFILE_MAJOR=55 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`" DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="10 11" diff -Nru openjdk-lts-11.0.20.1+1/make/data/cacerts/certignarootca openjdk-lts-11.0.21+9/make/data/cacerts/certignarootca --- openjdk-lts-11.0.20.1+1/make/data/cacerts/certignarootca 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/data/cacerts/certignarootca 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,43 @@ +Owner: CN=Certigna Root CA, OU=0002 48146308100036, O=Dhimyotis, C=FR +Issuer: CN=Certigna Root CA, OU=0002 48146308100036, O=Dhimyotis, C=FR +Serial number: cae91b89f155030da3e6416dc4e3a6e1 +Valid from: Tue Oct 01 08:32:27 GMT 2013 until: Sat Oct 01 08:32:27 GMT 2033 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 4096-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- diff -Nru openjdk-lts-11.0.20.1+1/make/data/cacerts/secomscrootca1 openjdk-lts-11.0.21+9/make/data/cacerts/secomscrootca1 --- openjdk-lts-11.0.20.1+1/make/data/cacerts/secomscrootca1 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/data/cacerts/secomscrootca1 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -Owner: OU=Security Communication RootCA1, O=SECOM Trust.net, C=JP -Issuer: OU=Security Communication RootCA1, O=SECOM Trust.net, C=JP -Serial number: 0 -Valid from: Tue Sep 30 04:20:49 GMT 2003 until: Sat Sep 30 04:20:49 GMT 2023 -Signature algorithm name: SHA1withRSA -Subject Public Key Algorithm: 2048-bit RSA key -Version: 3 ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------END CERTIFICATE----- diff -Nru openjdk-lts-11.0.20.1+1/make/data/publicsuffixlist/public_suffix_list.dat openjdk-lts-11.0.21+9/make/data/publicsuffixlist/public_suffix_list.dat --- openjdk-lts-11.0.20.1+1/make/data/publicsuffixlist/public_suffix_list.dat 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/data/publicsuffixlist/public_suffix_list.dat 2023-10-06 05:33:33.000000000 +0000 @@ -9,7 +9,7 @@ // ===BEGIN ICANN DOMAINS=== -// ac : https://en.wikipedia.org/wiki/.ac +// ac : http://nic.ac/rules.htm ac com.ac edu.ac @@ -22,8 +22,7 @@ ad nom.ad -// ae : https://en.wikipedia.org/wiki/.ae -// see also: "Domain Name Eligibility Policy" at http://www.aeda.ae/eng/aepolicy.php +// ae : https://tdra.gov.ae/en/aeda/ae-policies ae co.ae net.ae @@ -381,11 +380,29 @@ // biz : https://en.wikipedia.org/wiki/.biz biz -// bj : https://en.wikipedia.org/wiki/.bj +// bj : https://nic.bj/bj-suffixes.txt +// submitted by registry bj -asso.bj -barreau.bj -gouv.bj +africa.bj +agro.bj +architectes.bj +assur.bj +avocats.bj +co.bj +com.bj +eco.bj +econo.bj +edu.bj +info.bj +loisirs.bj +money.bj +net.bj +org.bj +ote.bj +resto.bj +restaurant.bj +tourism.bj +univ.bj // bm : http://www.bermudanic.bm/dnr-text.txt bm @@ -865,6 +882,7 @@ // cy : http://www.nic.cy/ // Submitted by registry Panayiotou Fotia +// namespace policies URL https://www.nic.cy/portal//sites/default/files/symfonia_gia_eggrafi.pdf cy ac.cy biz.cy @@ -872,10 +890,9 @@ ekloges.cy gov.cy ltd.cy -name.cy +mil.cy net.cy org.cy -parliament.cy press.cy pro.cy tm.cy @@ -1034,8 +1051,7 @@ // fo : https://en.wikipedia.org/wiki/.fo fo -// fr : http://www.afnic.fr/ -// domaines descriptifs : https://www.afnic.fr/medias/documents/Cadre_legal/Afnic_Naming_Policy_12122016_VEN.pdf +// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf fr asso.fr com.fr @@ -1043,7 +1059,7 @@ nom.fr prd.fr tm.fr -// domaines sectoriels : https://www.afnic.fr/en/products-and-services/the-fr-tld/sector-based-fr-domains-4.html +// Former "domaines sectoriels", still registration suffixes aeroport.fr avocat.fr avoues.fr @@ -1316,7 +1332,9 @@ ie gov.ie -// il : http://www.isoc.org.il/domains/ +// il : http://www.isoc.org.il/domains/ +// see also: https://en.isoc.org.il/il-cctld/registration-rules +// ISOC-IL (operated by .il Registry) il ac.il co.il @@ -1326,6 +1344,16 @@ muni.il net.il org.il +// xn--4dbrk0ce ("Israel", Hebrew) : IL +ישראל +// xn--4dbgdty6c.xn--4dbrk0ce. +אקדמיה.ישראל +// xn--5dbhl8d.xn--4dbrk0ce. +ישוב.ישראל +// xn--8dbq2a.xn--4dbrk0ce. +צהל.ישראל +// xn--hebda8b.xn--4dbrk0ce. +ממשל.ישראל // im : https://www.nic.im/ // Submitted by registry @@ -1341,22 +1369,51 @@ tv.im // in : https://en.wikipedia.org/wiki/.in -// see also: https://registry.in/Policies +// see also: https://registry.in/policies // Please note, that nic.in is not an official eTLD, but used by most // government institutions. in +5g.in +6g.in +ac.in +ai.in +am.in +bihar.in +biz.in +business.in +ca.in +cn.in co.in +com.in +coop.in +cs.in +delhi.in +dr.in +edu.in +er.in firm.in -net.in -org.in gen.in +gov.in +gujarat.in ind.in +info.in +int.in +internet.in +io.in +me.in +mil.in +net.in nic.in -ac.in -edu.in +org.in +pg.in +post.in +pro.in res.in -gov.in -mil.in +travel.in +tv.in +uk.in +up.in +us.in // info : https://en.wikipedia.org/wiki/.info info @@ -1366,7 +1423,7 @@ int eu.int -// io : http://www.nic.io/rules.html +// io : http://www.nic.io/rules.htm // list of other 2nd level tlds ? io com.io @@ -3765,11 +3822,10 @@ // ky : http://www.icta.ky/da_ky_reg_dom.php // Confirmed by registry 2008-06-17 ky -edu.ky -gov.ky com.ky -org.ky +edu.ky net.ky +org.ky // kz : https://en.wikipedia.org/wiki/.kz // see also: http://www.nic.kz/rules/index.jsp @@ -4013,555 +4069,8 @@ co.mu or.mu -// museum : http://about.museum/naming/ -// http://index.museum/ +// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ museum -academy.museum -agriculture.museum -air.museum -airguard.museum -alabama.museum -alaska.museum -amber.museum -ambulance.museum -american.museum -americana.museum -americanantiques.museum -americanart.museum -amsterdam.museum -and.museum -annefrank.museum -anthro.museum -anthropology.museum -antiques.museum -aquarium.museum -arboretum.museum -archaeological.museum -archaeology.museum -architecture.museum -art.museum -artanddesign.museum -artcenter.museum -artdeco.museum -arteducation.museum -artgallery.museum -arts.museum -artsandcrafts.museum -asmatart.museum -assassination.museum -assisi.museum -association.museum -astronomy.museum -atlanta.museum -austin.museum -australia.museum -automotive.museum -aviation.museum -axis.museum -badajoz.museum -baghdad.museum -bahn.museum -bale.museum -baltimore.museum -barcelona.museum -baseball.museum -basel.museum -baths.museum -bauern.museum -beauxarts.museum -beeldengeluid.museum -bellevue.museum -bergbau.museum -berkeley.museum -berlin.museum -bern.museum -bible.museum -bilbao.museum -bill.museum -birdart.museum -birthplace.museum -bonn.museum -boston.museum -botanical.museum -botanicalgarden.museum -botanicgarden.museum -botany.museum -brandywinevalley.museum -brasil.museum -bristol.museum -british.museum -britishcolumbia.museum -broadcast.museum -brunel.museum -brussel.museum -brussels.museum -bruxelles.museum -building.museum -burghof.museum -bus.museum -bushey.museum -cadaques.museum -california.museum -cambridge.museum -can.museum -canada.museum -capebreton.museum -carrier.museum -cartoonart.museum -casadelamoneda.museum -castle.museum -castres.museum -celtic.museum -center.museum -chattanooga.museum -cheltenham.museum -chesapeakebay.museum -chicago.museum -children.museum -childrens.museum -childrensgarden.museum -chiropractic.museum -chocolate.museum -christiansburg.museum -cincinnati.museum -cinema.museum -circus.museum -civilisation.museum -civilization.museum -civilwar.museum -clinton.museum -clock.museum -coal.museum -coastaldefence.museum -cody.museum -coldwar.museum -collection.museum -colonialwilliamsburg.museum -coloradoplateau.museum -columbia.museum -columbus.museum -communication.museum -communications.museum -community.museum -computer.museum -computerhistory.museum -comunicações.museum -contemporary.museum -contemporaryart.museum -convent.museum -copenhagen.museum -corporation.museum -correios-e-telecomunicações.museum -corvette.museum -costume.museum -countryestate.museum -county.museum -crafts.museum -cranbrook.museum -creation.museum -cultural.museum -culturalcenter.museum -culture.museum -cyber.museum -cymru.museum -dali.museum -dallas.museum -database.museum -ddr.museum -decorativearts.museum -delaware.museum -delmenhorst.museum -denmark.museum -depot.museum -design.museum -detroit.museum -dinosaur.museum -discovery.museum -dolls.museum -donostia.museum -durham.museum -eastafrica.museum -eastcoast.museum -education.museum -educational.museum -egyptian.museum -eisenbahn.museum -elburg.museum -elvendrell.museum -embroidery.museum -encyclopedic.museum -england.museum -entomology.museum -environment.museum -environmentalconservation.museum -epilepsy.museum -essex.museum -estate.museum -ethnology.museum -exeter.museum -exhibition.museum -family.museum -farm.museum -farmequipment.museum -farmers.museum -farmstead.museum -field.museum -figueres.museum -filatelia.museum -film.museum -fineart.museum -finearts.museum -finland.museum -flanders.museum -florida.museum -force.museum -fortmissoula.museum -fortworth.museum -foundation.museum -francaise.museum -frankfurt.museum -franziskaner.museum -freemasonry.museum -freiburg.museum -fribourg.museum -frog.museum -fundacio.museum -furniture.museum -gallery.museum -garden.museum -gateway.museum -geelvinck.museum -gemological.museum -geology.museum -georgia.museum -giessen.museum -glas.museum -glass.museum -gorge.museum -grandrapids.museum -graz.museum -guernsey.museum -halloffame.museum -hamburg.museum -handson.museum -harvestcelebration.museum -hawaii.museum -health.museum -heimatunduhren.museum -hellas.museum -helsinki.museum -hembygdsforbund.museum -heritage.museum -histoire.museum -historical.museum -historicalsociety.museum -historichouses.museum -historisch.museum -historisches.museum -history.museum -historyofscience.museum -horology.museum -house.museum -humanities.museum -illustration.museum -imageandsound.museum -indian.museum -indiana.museum -indianapolis.museum -indianmarket.museum -intelligence.museum -interactive.museum -iraq.museum -iron.museum -isleofman.museum -jamison.museum -jefferson.museum -jerusalem.museum -jewelry.museum -jewish.museum -jewishart.museum -jfk.museum -journalism.museum -judaica.museum -judygarland.museum -juedisches.museum -juif.museum -karate.museum -karikatur.museum -kids.museum -koebenhavn.museum -koeln.museum -kunst.museum -kunstsammlung.museum -kunstunddesign.museum -labor.museum -labour.museum -lajolla.museum -lancashire.museum -landes.museum -lans.museum -läns.museum -larsson.museum -lewismiller.museum -lincoln.museum -linz.museum -living.museum -livinghistory.museum -localhistory.museum -london.museum -losangeles.museum -louvre.museum -loyalist.museum -lucerne.museum -luxembourg.museum -luzern.museum -mad.museum -madrid.museum -mallorca.museum -manchester.museum -mansion.museum -mansions.museum -manx.museum -marburg.museum -maritime.museum -maritimo.museum -maryland.museum -marylhurst.museum -media.museum -medical.museum -medizinhistorisches.museum -meeres.museum -memorial.museum -mesaverde.museum -michigan.museum -midatlantic.museum -military.museum -mill.museum -miners.museum -mining.museum -minnesota.museum -missile.museum -missoula.museum -modern.museum -moma.museum -money.museum -monmouth.museum -monticello.museum -montreal.museum -moscow.museum -motorcycle.museum -muenchen.museum -muenster.museum -mulhouse.museum -muncie.museum -museet.museum -museumcenter.museum -museumvereniging.museum -music.museum -national.museum -nationalfirearms.museum -nationalheritage.museum -nativeamerican.museum -naturalhistory.museum -naturalhistorymuseum.museum -naturalsciences.museum -nature.museum -naturhistorisches.museum -natuurwetenschappen.museum -naumburg.museum -naval.museum -nebraska.museum -neues.museum -newhampshire.museum -newjersey.museum -newmexico.museum -newport.museum -newspaper.museum -newyork.museum -niepce.museum -norfolk.museum -north.museum -nrw.museum -nyc.museum -nyny.museum -oceanographic.museum -oceanographique.museum -omaha.museum -online.museum -ontario.museum -openair.museum -oregon.museum -oregontrail.museum -otago.museum -oxford.museum -pacific.museum -paderborn.museum -palace.museum -paleo.museum -palmsprings.museum -panama.museum -paris.museum -pasadena.museum -pharmacy.museum -philadelphia.museum -philadelphiaarea.museum -philately.museum -phoenix.museum -photography.museum -pilots.museum -pittsburgh.museum -planetarium.museum -plantation.museum -plants.museum -plaza.museum -portal.museum -portland.museum -portlligat.museum -posts-and-telecommunications.museum -preservation.museum -presidio.museum -press.museum -project.museum -public.museum -pubol.museum -quebec.museum -railroad.museum -railway.museum -research.museum -resistance.museum -riodejaneiro.museum -rochester.museum -rockart.museum -roma.museum -russia.museum -saintlouis.museum -salem.museum -salvadordali.museum -salzburg.museum -sandiego.museum -sanfrancisco.museum -santabarbara.museum -santacruz.museum -santafe.museum -saskatchewan.museum -satx.museum -savannahga.museum -schlesisches.museum -schoenbrunn.museum -schokoladen.museum -school.museum -schweiz.museum -science.museum -scienceandhistory.museum -scienceandindustry.museum -sciencecenter.museum -sciencecenters.museum -science-fiction.museum -sciencehistory.museum -sciences.museum -sciencesnaturelles.museum -scotland.museum -seaport.museum -settlement.museum -settlers.museum -shell.museum -sherbrooke.museum -sibenik.museum -silk.museum -ski.museum -skole.museum -society.museum -sologne.museum -soundandvision.museum -southcarolina.museum -southwest.museum -space.museum -spy.museum -square.museum -stadt.museum -stalbans.museum -starnberg.museum -state.museum -stateofdelaware.museum -station.museum -steam.museum -steiermark.museum -stjohn.museum -stockholm.museum -stpetersburg.museum -stuttgart.museum -suisse.museum -surgeonshall.museum -surrey.museum -svizzera.museum -sweden.museum -sydney.museum -tank.museum -tcm.museum -technology.museum -telekommunikation.museum -television.museum -texas.museum -textile.museum -theater.museum -time.museum -timekeeping.museum -topology.museum -torino.museum -touch.museum -town.museum -transport.museum -tree.museum -trolley.museum -trust.museum -trustee.museum -uhren.museum -ulm.museum -undersea.museum -university.museum -usa.museum -usantiques.museum -usarts.museum -uscountryestate.museum -usculture.museum -usdecorativearts.museum -usgarden.museum -ushistory.museum -ushuaia.museum -uslivinghistory.museum -utah.museum -uvic.museum -valley.museum -vantaa.museum -versailles.museum -viking.museum -village.museum -virginia.museum -virtual.museum -virtuel.museum -vlaanderen.museum -volkenkunde.museum -wales.museum -wallonie.museum -war.museum -washingtondc.museum -watchandclock.museum -watch-and-clock.museum -western.museum -westfalen.museum -whaling.museum -wildlife.museum -williamsburg.museum -windmill.museum -workshop.museum -york.museum -yorkshire.museum -yosemite.museum -youth.museum -zoological.museum -zoology.museum -ירושלים.museum -иком.museum // mv : https://en.wikipedia.org/wiki/.mv // "mv" included because, contra Wikipedia, google.mv exists. @@ -5804,7 +5313,7 @@ zgora.pl zgorzelec.pl -// pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf pm // pn : http://www.government.pn/PnRegistry/policies.htm @@ -5902,7 +5411,7 @@ org.qa sch.qa -// re : http://www.afnic.re/obtenir/chartes/nommage-re/annexe-descriptifs +// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf re asso.re com.re @@ -6037,7 +5546,7 @@ edu.sg per.sg -// sh : http://www.nic.sh/registrar.html +// sh : http://nic.sh/rules.htm sh com.sh net.sh @@ -6159,7 +5668,7 @@ // http://www.telnic.org/ tel -// tf : https://en.wikipedia.org/wiki/.tf +// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf tf // tg : https://en.wikipedia.org/wiki/.tg @@ -6778,7 +6287,7 @@ net.vu org.vu -// wf : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf wf // ws : https://en.wikipedia.org/wiki/.ws @@ -6790,7 +6299,7 @@ gov.ws edu.ws -// yt : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf +// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf yt // IDN ccTLDs @@ -7132,7 +6641,7 @@ // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2021-11-13T15:12:42Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2023-04-14T15:13:16Z // This list is auto-generated, don't edit it manually. // aaa : 2015-02-26 American Automobile Association, Inc. aaa @@ -7182,9 +6691,6 @@ // actor : 2013-12-12 Dog Beach, LLC actor -// adac : 2015-07-16 Allgemeiner Deutscher Automobil-Club e.V. (ADAC) -adac - // ads : 2014-12-04 Charleston Road Registry Inc. ads @@ -7197,9 +6703,6 @@ // aetna : 2015-05-21 Aetna Life Insurance Company aetna -// afamilycompany : 2015-07-23 Johnson Shareholdings, Inc. -afamilycompany - // afl : 2014-10-02 Australian Football League afl @@ -7305,7 +6808,7 @@ // aramco : 2014-11-20 Aramco Services Company aramco -// archi : 2014-02-06 Afilias Limited +// archi : 2014-02-06 Identity Digital Limited archi // army : 2014-03-06 Dog Beach, LLC @@ -7338,7 +6841,7 @@ // audible : 2015-06-25 Amazon Registry Services, Inc. audible -// audio : 2014-03-20 UNR Corp. +// audio : 2014-03-20 XYZ.COM LLC audio // auspost : 2015-08-13 Australian Postal Corporation @@ -7353,7 +6856,7 @@ // autos : 2014-01-09 XYZ.COM LLC autos -// avianca : 2015-01-08 Avianca Holdings S.A. +// avianca : 2015-01-08 Avianca Inc. avianca // aws : 2015-06-25 AWS Registry LLC @@ -7449,7 +6952,7 @@ // bestbuy : 2015-07-31 BBY Solutions, Inc. bestbuy -// bet : 2015-05-07 Afilias Limited +// bet : 2015-05-07 Identity Digital Limited bet // bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited @@ -7470,13 +6973,13 @@ // bingo : 2014-12-04 Binky Moon, LLC bingo -// bio : 2014-03-06 Afilias Limited +// bio : 2014-03-06 Identity Digital Limited bio -// black : 2014-01-16 Afilias Limited +// black : 2014-01-16 Identity Digital Limited black -// blackfriday : 2014-01-16 UNR Corp. +// blackfriday : 2014-01-16 Registry Services, LLC blackfriday // blockbuster : 2015-07-30 Dish DBS Corporation @@ -7488,7 +6991,7 @@ // bloomberg : 2014-07-17 Bloomberg IP Holdings LLC bloomberg -// blue : 2013-11-07 Afilias Limited +// blue : 2013-11-07 Identity Digital Limited blue // bms : 2014-10-30 Bristol-Myers Squibb Company @@ -7530,7 +7033,7 @@ // bostik : 2015-05-28 Bostik SA bostik -// boston : 2015-12-10 Boston TLD Management, LLC +// boston : 2015-12-10 Registry Services, LLC boston // bot : 2014-12-18 Amazon Registry Services, Inc. @@ -7560,12 +7063,6 @@ // brussels : 2014-02-06 DNS.be vzw brussels -// budapest : 2013-11-21 Minds + Machines Group Limited -budapest - -// bugatti : 2015-07-23 Bugatti International SA -bugatti - // build : 2013-11-07 Plan Bee LLC build @@ -7599,7 +7096,7 @@ // calvinklein : 2015-07-30 PVH gTLD Holdings LLC calvinklein -// cam : 2016-04-21 AC Webconnecting Holding B.V. +// cam : 2016-04-21 Cam Connecting SARL cam // camera : 2013-08-27 Binky Moon, LLC @@ -7608,9 +7105,6 @@ // camp : 2013-11-07 Binky Moon, LLC camp -// cancerresearch : 2014-05-15 Australian Cancer Research Foundation -cancerresearch - // canon : 2014-09-12 Canon Inc. canon @@ -7647,7 +7141,7 @@ // casa : 2013-11-21 Registry Services, LLC casa -// case : 2015-09-03 Helium TLDs Ltd +// case : 2015-09-03 Digity, LLC case // cash : 2014-03-06 Binky Moon, LLC @@ -7695,7 +7189,7 @@ // channel : 2014-05-08 Charleston Road Registry Inc. channel -// charity : 2018-04-11 Binky Moon, LLC +// charity : 2018-04-11 Public Interest Registry charity // chase : 2015-04-30 JPMorgan Chase Bank, National Association @@ -7710,7 +7204,7 @@ // chintai : 2015-06-11 CHINTAI Corporation chintai -// christmas : 2013-11-21 UNR Corp. +// christmas : 2013-11-21 XYZ.COM LLC christmas // chrome : 2014-07-24 Charleston Road Registry Inc. @@ -7749,7 +7243,7 @@ // cleaning : 2013-12-05 Binky Moon, LLC cleaning -// click : 2014-06-05 UNR Corp. +// click : 2014-06-05 Internet Naming Company LLC click // clinic : 2014-03-20 Binky Moon, LLC @@ -7833,7 +7327,7 @@ // corsica : 2014-09-25 Collectivité de Corse corsica -// country : 2013-12-19 DotCountry LLC +// country : 2013-12-19 Internet Naming Company LLC country // coupon : 2015-02-26 Amazon Registry Services, Inc. @@ -7842,7 +7336,7 @@ // coupons : 2015-03-26 Binky Moon, LLC coupons -// courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD +// courses : 2014-12-04 Registry Services, LLC courses // cpa : 2019-06-10 American Institute of Certified Public Accountants @@ -7872,9 +7366,6 @@ // cruises : 2013-12-05 Binky Moon, LLC cruises -// csc : 2014-09-25 Alliance-One Services, Inc. -csc - // cuisinella : 2014-04-03 SCHMIDT GROUPE S.A.S. cuisinella @@ -7962,7 +7453,7 @@ // diamonds : 2013-09-22 Binky Moon, LLC diamonds -// diet : 2014-06-26 UNR Corp. +// diet : 2014-06-26 XYZ.COM LLC diet // digital : 2014-03-06 Binky Moon, LLC @@ -8016,9 +7507,6 @@ // dubai : 2015-01-01 Dubai Smart Government Department dubai -// duck : 2015-07-23 Johnson Shareholdings, Inc. -duck - // dunlop : 2015-07-02 The Goodyear Tire & Rubber Company dunlop @@ -8034,7 +7522,7 @@ // dvr : 2016-05-26 DISH Technologies L.L.C. dvr -// earth : 2014-12-04 Interlink Co., Ltd. +// earth : 2014-12-04 Interlink Systems Innovation Institute K.K. earth // eat : 2014-01-23 Charleston Road Registry Inc. @@ -8211,7 +7699,7 @@ // florist : 2013-11-07 Binky Moon, LLC florist -// flowers : 2014-10-09 UNR Corp. +// flowers : 2014-10-09 XYZ.COM LLC flowers // fly : 2014-05-08 Charleston Road Registry Inc. @@ -8241,7 +7729,7 @@ // forum : 2015-04-02 Fegistry, LLC forum -// foundation : 2013-12-05 Binky Moon, LLC +// foundation : 2013-12-05 Public Interest Registry foundation // fox : 2015-09-11 FOX Registry, LLC @@ -8298,7 +7786,7 @@ // gallup : 2015-02-19 Gallup, Inc. gallup -// game : 2015-05-28 UNR Corp. +// game : 2015-05-28 XYZ.COM LLC game // games : 2015-05-28 Dog Beach, LLC @@ -8322,7 +7810,7 @@ // gea : 2014-12-04 GEA Group Aktiengesellschaft gea -// gent : 2014-01-23 COMBELL NV +// gent : 2014-01-23 Easyhost BV gent // genting : 2015-03-12 Resorts World Inc Pte. Ltd. @@ -8340,22 +7828,19 @@ // gifts : 2014-07-03 Binky Moon, LLC gifts -// gives : 2014-03-06 Dog Beach, LLC +// gives : 2014-03-06 Public Interest Registry gives -// giving : 2014-11-13 Giving Limited +// giving : 2014-11-13 Public Interest Registry giving -// glade : 2015-07-23 Johnson Shareholdings, Inc. -glade - // glass : 2013-11-07 Binky Moon, LLC glass // gle : 2014-07-24 Charleston Road Registry Inc. gle -// global : 2014-04-17 Dot Global Domain Registry Limited +// global : 2014-04-17 Identity Digital Limited global // globo : 2013-12-19 Globo Comunicação e Participações S.A @@ -8412,7 +7897,7 @@ // gratis : 2014-03-20 Binky Moon, LLC gratis -// green : 2014-05-08 Afilias Limited +// green : 2014-05-08 Identity Digital Limited green // gripe : 2014-03-06 Binky Moon, LLC @@ -8436,7 +7921,7 @@ // guide : 2013-09-13 Binky Moon, LLC guide -// guitars : 2013-11-14 UNR Corp. +// guitars : 2013-11-14 XYZ.COM LLC guitars // guru : 2013-08-27 Binky Moon, LLC @@ -8469,7 +7954,7 @@ // healthcare : 2014-06-12 Binky Moon, LLC healthcare -// help : 2014-06-26 UNR Corp. +// help : 2014-06-26 Innovation service Limited help // helsinki : 2015-02-05 City of Helsinki @@ -8484,7 +7969,7 @@ // hgtv : 2015-07-02 Lifestyle Domain Holdings, Inc. hgtv -// hiphop : 2014-03-06 UNR Corp. +// hiphop : 2014-03-06 Dot Hip Hop, LLC hiphop // hisamitsu : 2015-07-16 Hisamitsu Pharmaceutical Co.,Inc. @@ -8493,7 +7978,7 @@ // hitachi : 2014-10-31 Hitachi, Ltd. hitachi -// hiv : 2014-03-13 UNR Corp. +// hiv : 2014-03-13 Internet Naming Company LLC hiv // hkt : 2015-05-14 PCCW-HKT DataCom Services Limited @@ -8532,7 +8017,7 @@ // host : 2014-04-17 Radix FZC host -// hosting : 2014-05-29 UNR Corp. +// hosting : 2014-05-29 XYZ.COM LLC hosting // hot : 2015-08-27 Amazon Registry Services, Inc. @@ -8697,7 +8182,7 @@ // jprs : 2014-09-18 Japan Registry Services Co., Ltd. jprs -// juegos : 2014-03-20 UNR Corp. +// juegos : 2014-03-20 Internet Naming Company LLC juegos // juniper : 2015-07-30 JUNIPER NETWORKS, INC. @@ -8727,7 +8212,7 @@ // kids : 2021-08-13 DotKids Foundation Limited kids -// kim : 2013-09-23 Afilias Limited +// kim : 2013-09-23 Identity Digital Limited kim // kinder : 2014-11-07 Ferrero Trading Lux S.A. @@ -8796,7 +8281,7 @@ // lasalle : 2015-04-02 Jones Lang LaSalle Incorporated lasalle -// lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico +// lat : 2014-10-16 XYZ.COM LLC lat // latino : 2015-07-30 Dish DBS Corporation @@ -8832,7 +8317,7 @@ // lexus : 2015-04-23 TOYOTA MOTOR CORPORATION lexus -// lgbt : 2014-05-08 Afilias Limited +// lgbt : 2014-05-08 Identity Digital Limited lgbt // lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG @@ -8865,10 +8350,7 @@ // lincoln : 2014-11-13 Ford Motor Company lincoln -// linde : 2014-12-04 Linde Aktiengesellschaft -linde - -// link : 2013-11-14 UNR Corp. +// link : 2013-11-14 Nova Registry Ltd link // lipsy : 2015-06-25 Lipsy Ltd @@ -8880,13 +8362,10 @@ // living : 2015-07-30 Lifestyle Domain Holdings, Inc. living -// lixil : 2015-03-19 LIXIL Group Corporation -lixil - -// llc : 2017-12-14 Afilias Limited +// llc : 2017-12-14 Identity Digital Limited llc -// llp : 2019-08-26 UNR Corp. +// llp : 2019-08-26 Intercap Registry Inc. llp // loan : 2014-11-20 dot Loan Limited @@ -8901,10 +8380,7 @@ // locus : 2015-06-25 Locus Analytics LLC locus -// loft : 2015-07-30 Annco, Inc. -loft - -// lol : 2015-01-30 UNR Corp. +// lol : 2015-01-30 XYZ.COM LLC lol // london : 2013-11-14 Dot London Domains Limited @@ -8913,7 +8389,7 @@ // lotte : 2014-11-07 Lotte Holdings Co., Ltd. lotte -// lotto : 2014-04-10 Afilias Limited +// lotto : 2014-04-10 Identity Digital Limited lotto // love : 2014-12-22 Merchant Law Group LLP @@ -8940,9 +8416,6 @@ // luxury : 2013-10-17 Luxury Partners, LLC luxury -// macys : 2015-07-31 Macys, Inc. -macys - // madrid : 2014-05-01 Comunidad de Madrid madrid @@ -9021,7 +8494,7 @@ // merckmsd : 2016-07-14 MSD Registry Holdings, Inc. merckmsd -// miami : 2013-12-19 Minds + Machines Group Limited +// miami : 2013-12-19 Registry Services, LLC miami // microsoft : 2014-12-18 Microsoft Corporation @@ -9054,13 +8527,13 @@ // moda : 2013-11-07 Dog Beach, LLC moda -// moe : 2013-11-13 Interlink Co., Ltd. +// moe : 2013-11-13 Interlink Systems Innovation Institute K.K. moe // moi : 2014-12-18 Amazon Registry Services, Inc. moi -// mom : 2015-04-16 UNR Corp. +// mom : 2015-04-16 XYZ.COM LLC mom // monash : 2013-09-30 Monash University @@ -9216,9 +8689,6 @@ // observer : 2015-04-30 Dog Beach, LLC observer -// off : 2015-07-23 Johnson Shareholdings, Inc. -off - // office : 2015-03-12 Microsoft Corporation office @@ -9264,7 +8734,7 @@ // orange : 2015-03-12 Orange Brand Services Limited orange -// organic : 2014-03-27 Afilias Limited +// organic : 2014-03-27 Identity Digital Limited organic // origins : 2015-10-01 The Estée Lauder Companies Inc. @@ -9285,7 +8755,7 @@ // page : 2014-12-04 Charleston Road Registry Inc. page -// panasonic : 2015-07-30 Panasonic Corporation +// panasonic : 2015-07-30 Panasonic Holdings Corporation panasonic // paris : 2014-01-30 City of Paris @@ -9312,7 +8782,7 @@ // pccw : 2015-05-14 PCCW Enterprises Limited pccw -// pet : 2015-05-07 Afilias Limited +// pet : 2015-05-07 Identity Digital Limited pet // pfizer : 2015-09-11 Pfizer Inc. @@ -9330,7 +8800,7 @@ // phone : 2016-06-02 Dish DBS Corporation phone -// photo : 2013-11-14 UNR Corp. +// photo : 2013-11-14 Registry Services, LLC photo // photography : 2013-09-20 Binky Moon, LLC @@ -9342,7 +8812,7 @@ // physio : 2014-05-01 PhysBiz Pty Ltd physio -// pics : 2013-11-14 UNR Corp. +// pics : 2013-11-14 XYZ.COM LLC pics // pictet : 2014-06-26 Pictet Europe S.A. @@ -9360,7 +8830,7 @@ // ping : 2015-06-11 Ping Registry Provider, Inc. ping -// pink : 2013-10-01 Afilias Limited +// pink : 2013-10-01 Identity Digital Limited pink // pioneer : 2015-07-16 Pioneer Corporation @@ -9390,7 +8860,7 @@ // pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG pohl -// poker : 2014-07-03 Afilias Limited +// poker : 2014-07-03 Identity Digital Limited poker // politie : 2015-08-20 Politie Nederland @@ -9423,13 +8893,13 @@ // progressive : 2015-07-23 Progressive Casualty Insurance Company progressive -// promo : 2014-12-18 Afilias Limited +// promo : 2014-12-18 Identity Digital Limited promo // properties : 2013-12-05 Binky Moon, LLC properties -// property : 2014-05-22 UNR Corp. +// property : 2014-05-22 Internet Naming Company LLC property // protection : 2015-04-23 XYZ.COM LLC @@ -9447,7 +8917,7 @@ // pwc : 2015-10-29 PricewaterhouseCoopers LLP pwc -// qpon : 2013-11-14 dotCOOL, Inc. +// qpon : 2013-11-14 dotQPON LLC qpon // quebec : 2013-12-19 PointQuébec Inc @@ -9462,9 +8932,6 @@ // radio : 2016-07-21 European Broadcasting Union (EBU) radio -// raid : 2015-07-23 Johnson Shareholdings, Inc. -raid - // read : 2014-12-18 Amazon Registry Services, Inc. read @@ -9480,7 +8947,7 @@ // recipes : 2013-10-17 Binky Moon, LLC recipes -// red : 2013-11-07 Afilias Limited +// red : 2013-11-07 Identity Digital Limited red // redstone : 2014-10-31 Redstone Haute Couture Co., Ltd. @@ -9576,7 +9043,7 @@ // rugby : 2016-12-15 World Rugby Strategic Developments Limited rugby -// ruhr : 2013-10-02 regiodot GmbH & Co. KG +// ruhr : 2013-10-02 dotSaarland GmbH ruhr // run : 2015-03-19 Binky Moon, LLC @@ -9669,9 +9136,6 @@ // science : 2014-09-11 dot Science Limited science -// scjohnson : 2015-07-23 Johnson Shareholdings, Inc. -scjohnson - // scot : 2014-01-23 Dot Scot Registry Limited scot @@ -9699,9 +9163,6 @@ // services : 2014-02-27 Binky Moon, LLC services -// ses : 2015-07-23 SES -ses - // seven : 2015-08-06 Seven West Media Ltd seven @@ -9711,7 +9172,7 @@ // sex : 2014-11-13 ICM Registry SX LLC sex -// sexy : 2013-09-11 UNR Corp. +// sexy : 2013-09-11 Internet Naming Company LLC sexy // sfr : 2015-08-13 Societe Francaise du Radiotelephone - SFR @@ -9732,7 +9193,7 @@ // shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. shia -// shiksha : 2013-11-14 Afilias Limited +// shiksha : 2013-11-14 Identity Digital Limited shiksha // shoes : 2013-10-02 Binky Moon, LLC @@ -9765,7 +9226,7 @@ // site : 2015-01-15 Radix FZC site -// ski : 2015-04-09 Afilias Limited +// ski : 2015-04-09 Identity Digital Limited ski // skin : 2015-01-15 XYZ.COM LLC @@ -9786,7 +9247,7 @@ // smile : 2014-12-18 Amazon Registry Services, Inc. smile -// sncf : 2015-02-19 Société Nationale des Chemins de fer Francais S N C F +// sncf : 2015-02-19 Société Nationale SNCF sncf // soccer : 2015-03-26 Binky Moon, LLC @@ -9870,7 +9331,7 @@ // studio : 2015-02-11 Dog Beach, LLC studio -// study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD +// study : 2014-12-11 Registry Services, LLC study // style : 2014-12-04 Binky Moon, LLC @@ -9930,7 +9391,7 @@ // tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" tatar -// tattoo : 2013-08-30 UNR Corp. +// tattoo : 2013-08-30 Top Level Design, LLC tattoo // tax : 2014-03-20 Binky Moon, LLC @@ -10023,7 +9484,7 @@ // toshiba : 2014-04-10 TOSHIBA Corporation toshiba -// total : 2015-08-06 Total SA +// total : 2015-08-06 TotalEnergies SE total // tours : 2015-01-22 Binky Moon, LLC @@ -10059,7 +9520,7 @@ // travelersinsurance : 2015-03-26 Travelers TLD, LLC travelersinsurance -// trust : 2014-10-16 UNR Corp. +// trust : 2014-10-16 Internet Naming Company LLC trust // trv : 2015-03-26 Travelers TLD, LLC @@ -10206,7 +9667,7 @@ // watch : 2013-11-14 Binky Moon, LLC watch -// watches : 2014-12-22 Afilias Limited +// watches : 2014-12-22 Identity Digital Limited watches // weather : 2015-01-08 International Business Machines Corporation @@ -10341,7 +9802,7 @@ // xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited 网站 -// xn--6frz82g : 2013-09-23 Afilias Limited +// xn--6frz82g : 2013-09-23 Identity Digital Limited 移动 // xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited @@ -10458,9 +9919,6 @@ // xn--jlq480n2rg : 2019-12-19 Amazon Registry Services, Inc. 亚马逊 -// xn--jlq61u9w7b : 2015-01-08 Nokia Corporation -诺基亚 - // xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc. 食品 @@ -10648,6 +10106,14 @@ // Submitted by accesso Team *.devcdnaccesso.com +// Acorn Labs : https://acorn.io +// Submitted by Craig Jellick +*.on-acorn.io + +// ActiveTrail: https://www.activetrail.biz/ +// Submitted by Ofer Kalaora +activetrail.biz + // Adobe : https://www.adobe.com/ // Submitted by Ian Boston and Lars Trieloff adobeaemcloud.com @@ -10657,10 +10123,43 @@ hlx.page hlx3.page +// Adobe Developer Platform : https://developer.adobe.com +// Submitted by Jesse MacFadyen +adobeio-static.net +adobeioruntime.net + // Agnat sp. z o.o. : https://domena.pl // Submitted by Przemyslaw Plewa beep.pl +// Airkit : https://www.airkit.com/ +// Submitted by Grant Cooksey +airkitapps.com +airkitapps-au.com +airkitapps.eu + +// Aiven: https://aiven.io/ +// Submitted by Etienne Stalmans +aivencloud.com + +// Akamai : https://www.akamai.com/ +// Submitted by Akamai Team +akadns.net +akamai.net +akamai-staging.net +akamaiedge.net +akamaiedge-staging.net +akamaihd.net +akamaihd-staging.net +akamaiorigin.net +akamaiorigin-staging.net +akamaized.net +akamaized-staging.net +edgekey.net +edgekey-staging.net +edgesuite.net +edgesuite-staging.net + // alboto.ca : http://alboto.ca // Submitted by Anton Avramov barsy.ca @@ -10682,19 +10181,134 @@ // Submitted by Cyril alwaysdata.net -// Amazon CloudFront : https://aws.amazon.com/cloudfront/ +// Amaze Software : https://amaze.co +// Submitted by Domain Admin +myamaze.net + +// Amazon : https://www.amazon.com/ +// Submitted by AWS Security +// Subsections of Amazon/subsidiaries will appear until "concludes" tag + +// Amazon CloudFront // Submitted by Donavan Miller +// Reference: 54144616-fd49-4435-8535-19c6a601bdb3 cloudfront.net -// Amazon Elastic Compute Cloud : https://aws.amazon.com/ec2/ +// Amazon EC2 // Submitted by Luke Wells +// Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 *.compute.amazonaws.com *.compute-1.amazonaws.com *.compute.amazonaws.com.cn us-east-1.amazonaws.com -// Amazon Elastic Beanstalk : https://aws.amazon.com/elasticbeanstalk/ +// Amazon S3 +// Submitted by Luke Wells +// Reference: d068bd97-f0a9-4838-a6d8-954b622ef4ae +s3.cn-north-1.amazonaws.com.cn +s3.dualstack.ap-northeast-1.amazonaws.com +s3.dualstack.ap-northeast-2.amazonaws.com +s3.ap-northeast-2.amazonaws.com +s3-website.ap-northeast-2.amazonaws.com +s3.dualstack.ap-south-1.amazonaws.com +s3.ap-south-1.amazonaws.com +s3-website.ap-south-1.amazonaws.com +s3.dualstack.ap-southeast-1.amazonaws.com +s3.dualstack.ap-southeast-2.amazonaws.com +s3.dualstack.ca-central-1.amazonaws.com +s3.ca-central-1.amazonaws.com +s3-website.ca-central-1.amazonaws.com +s3.dualstack.eu-central-1.amazonaws.com +s3.eu-central-1.amazonaws.com +s3-website.eu-central-1.amazonaws.com +s3.dualstack.eu-west-1.amazonaws.com +s3.dualstack.eu-west-2.amazonaws.com +s3.eu-west-2.amazonaws.com +s3-website.eu-west-2.amazonaws.com +s3.dualstack.eu-west-3.amazonaws.com +s3.eu-west-3.amazonaws.com +s3-website.eu-west-3.amazonaws.com +s3.amazonaws.com +s3-ap-northeast-1.amazonaws.com +s3-ap-northeast-2.amazonaws.com +s3-ap-south-1.amazonaws.com +s3-ap-southeast-1.amazonaws.com +s3-ap-southeast-2.amazonaws.com +s3-ca-central-1.amazonaws.com +s3-eu-central-1.amazonaws.com +s3-eu-west-1.amazonaws.com +s3-eu-west-2.amazonaws.com +s3-eu-west-3.amazonaws.com +s3-external-1.amazonaws.com +s3-fips-us-gov-west-1.amazonaws.com +s3-sa-east-1.amazonaws.com +s3-us-east-2.amazonaws.com +s3-us-gov-west-1.amazonaws.com +s3-us-west-1.amazonaws.com +s3-us-west-2.amazonaws.com +s3-website-ap-northeast-1.amazonaws.com +s3-website-ap-southeast-1.amazonaws.com +s3-website-ap-southeast-2.amazonaws.com +s3-website-eu-west-1.amazonaws.com +s3-website-sa-east-1.amazonaws.com +s3-website-us-east-1.amazonaws.com +s3-website-us-west-1.amazonaws.com +s3-website-us-west-2.amazonaws.com +s3.dualstack.sa-east-1.amazonaws.com +s3.dualstack.us-east-1.amazonaws.com +s3.dualstack.us-east-2.amazonaws.com +s3.us-east-2.amazonaws.com +s3-website.us-east-2.amazonaws.com + +// AWS Cloud9 +// Submitted by: AWS Security +// Reference: 2b6dfa9a-3a7f-4367-b2e7-0321e77c0d59 +vfs.cloud9.af-south-1.amazonaws.com +webview-assets.cloud9.af-south-1.amazonaws.com +vfs.cloud9.ap-east-1.amazonaws.com +webview-assets.cloud9.ap-east-1.amazonaws.com +vfs.cloud9.ap-northeast-1.amazonaws.com +webview-assets.cloud9.ap-northeast-1.amazonaws.com +vfs.cloud9.ap-northeast-2.amazonaws.com +webview-assets.cloud9.ap-northeast-2.amazonaws.com +vfs.cloud9.ap-northeast-3.amazonaws.com +webview-assets.cloud9.ap-northeast-3.amazonaws.com +vfs.cloud9.ap-south-1.amazonaws.com +webview-assets.cloud9.ap-south-1.amazonaws.com +vfs.cloud9.ap-southeast-1.amazonaws.com +webview-assets.cloud9.ap-southeast-1.amazonaws.com +vfs.cloud9.ap-southeast-2.amazonaws.com +webview-assets.cloud9.ap-southeast-2.amazonaws.com +vfs.cloud9.ca-central-1.amazonaws.com +webview-assets.cloud9.ca-central-1.amazonaws.com +vfs.cloud9.eu-central-1.amazonaws.com +webview-assets.cloud9.eu-central-1.amazonaws.com +vfs.cloud9.eu-north-1.amazonaws.com +webview-assets.cloud9.eu-north-1.amazonaws.com +vfs.cloud9.eu-south-1.amazonaws.com +webview-assets.cloud9.eu-south-1.amazonaws.com +vfs.cloud9.eu-west-1.amazonaws.com +webview-assets.cloud9.eu-west-1.amazonaws.com +vfs.cloud9.eu-west-2.amazonaws.com +webview-assets.cloud9.eu-west-2.amazonaws.com +vfs.cloud9.eu-west-3.amazonaws.com +webview-assets.cloud9.eu-west-3.amazonaws.com +vfs.cloud9.me-south-1.amazonaws.com +webview-assets.cloud9.me-south-1.amazonaws.com +vfs.cloud9.sa-east-1.amazonaws.com +webview-assets.cloud9.sa-east-1.amazonaws.com +vfs.cloud9.us-east-1.amazonaws.com +webview-assets.cloud9.us-east-1.amazonaws.com +vfs.cloud9.us-east-2.amazonaws.com +webview-assets.cloud9.us-east-2.amazonaws.com +vfs.cloud9.us-west-1.amazonaws.com +webview-assets.cloud9.us-west-1.amazonaws.com +vfs.cloud9.us-west-2.amazonaws.com +webview-assets.cloud9.us-west-2.amazonaws.com + +// AWS Elastic Beanstalk // Submitted by Luke Wells +// Reference: aa202394-43a0-4857-b245-8db04549137e cn-north-1.eb.amazonaws.com.cn cn-northwest-1.eb.amazonaws.com.cn elasticbeanstalk.com @@ -10716,71 +10330,24 @@ us-west-1.elasticbeanstalk.com us-west-2.elasticbeanstalk.com -// Amazon Elastic Load Balancing : https://aws.amazon.com/elasticloadbalancing/ +// (AWS) Elastic Load Balancing // Submitted by Luke Wells -*.elb.amazonaws.com +// Reference: 12a3d528-1bac-4433-a359-a395867ffed2 *.elb.amazonaws.com.cn +*.elb.amazonaws.com -// Amazon Global Accelerator : https://aws.amazon.com/global-accelerator/ +// AWS Global Accelerator // Submitted by Daniel Massaguer +// Reference: d916759d-a08b-4241-b536-4db887383a6a awsglobalaccelerator.com -// Amazon S3 : https://aws.amazon.com/s3/ -// Submitted by Luke Wells -s3.amazonaws.com -s3-ap-northeast-1.amazonaws.com -s3-ap-northeast-2.amazonaws.com -s3-ap-south-1.amazonaws.com -s3-ap-southeast-1.amazonaws.com -s3-ap-southeast-2.amazonaws.com -s3-ca-central-1.amazonaws.com -s3-eu-central-1.amazonaws.com -s3-eu-west-1.amazonaws.com -s3-eu-west-2.amazonaws.com -s3-eu-west-3.amazonaws.com -s3-external-1.amazonaws.com -s3-fips-us-gov-west-1.amazonaws.com -s3-sa-east-1.amazonaws.com -s3-us-gov-west-1.amazonaws.com -s3-us-east-2.amazonaws.com -s3-us-west-1.amazonaws.com -s3-us-west-2.amazonaws.com -s3.ap-northeast-2.amazonaws.com -s3.ap-south-1.amazonaws.com -s3.cn-north-1.amazonaws.com.cn -s3.ca-central-1.amazonaws.com -s3.eu-central-1.amazonaws.com -s3.eu-west-2.amazonaws.com -s3.eu-west-3.amazonaws.com -s3.us-east-2.amazonaws.com -s3.dualstack.ap-northeast-1.amazonaws.com -s3.dualstack.ap-northeast-2.amazonaws.com -s3.dualstack.ap-south-1.amazonaws.com -s3.dualstack.ap-southeast-1.amazonaws.com -s3.dualstack.ap-southeast-2.amazonaws.com -s3.dualstack.ca-central-1.amazonaws.com -s3.dualstack.eu-central-1.amazonaws.com -s3.dualstack.eu-west-1.amazonaws.com -s3.dualstack.eu-west-2.amazonaws.com -s3.dualstack.eu-west-3.amazonaws.com -s3.dualstack.sa-east-1.amazonaws.com -s3.dualstack.us-east-1.amazonaws.com -s3.dualstack.us-east-2.amazonaws.com -s3-website-us-east-1.amazonaws.com -s3-website-us-west-1.amazonaws.com -s3-website-us-west-2.amazonaws.com -s3-website-ap-northeast-1.amazonaws.com -s3-website-ap-southeast-1.amazonaws.com -s3-website-ap-southeast-2.amazonaws.com -s3-website-eu-west-1.amazonaws.com -s3-website-sa-east-1.amazonaws.com -s3-website.ap-northeast-2.amazonaws.com -s3-website.ap-south-1.amazonaws.com -s3-website.ca-central-1.amazonaws.com -s3-website.eu-central-1.amazonaws.com -s3-website.eu-west-2.amazonaws.com -s3-website.eu-west-3.amazonaws.com -s3-website.us-east-2.amazonaws.com +// eero +// Submitted by Yue Kang +// Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 +eero.online +eero-stage.online + +// concludes Amazon // Amune : https://amune.org/ // Submitted by Team Amune @@ -10833,6 +10400,14 @@ // Submitted by Sam Smyth cdn.prod.atlassian-dev.net +// Authentick UG (haftungsbeschränkt) : https://authentick.net +// Submitted by Lukas Reschke +translated.page + +// Autocode : https://autocode.com +// Submitted by Jacob Lee +autocode.dev + // AVM : https://avm.de // Submitted by Andreas Weise myfritz.net @@ -10847,7 +10422,7 @@ *.advisor.ws // AZ.pl sp. z.o.o: https://az.pl -// Submited by Krzysztof Wolski +// Submitted by Krzysztof Wolski ecommerce-shop.pl // b-data GmbH : https://www.b-data.io @@ -10873,6 +10448,26 @@ app.banzaicloud.io *.backyards.banzaicloud.io +// BASE, Inc. : https://binc.jp +// Submitted by Yuya NAGASAWA +base.ec +official.ec +buyshop.jp +fashionstore.jp +handcrafted.jp +kawaiishop.jp +supersale.jp +theshop.jp +shopselect.net +base.shop + +// BeagleBoard.org Foundation : https://beagleboard.org +// Submitted by Jason Kridner +beagleboard.io + +// Beget Ltd +// Submitted by Lev Nekrasov +*.beget.app // BetaInABox // Submitted by Adrian @@ -10941,6 +10536,11 @@ // Submitted by Marcus Popp mycd.eu +// Canva Pty Ltd : https://canva.com/ +// Submitted by Joel Aquilina +canva-apps.cn +canva-apps.com + // Carrd : https://carrd.co // Submitted by AJ drr.ac @@ -11070,8 +10670,11 @@ // Cloudflare, Inc. : https://www.cloudflare.com/ // Submitted by Cloudflare Team -pages.dev +cf-ipfs.com +cloudflare-ipfs.com trycloudflare.com +pages.dev +r2.dev workers.dev // Clovyr : https://clovyr.io @@ -11115,6 +10718,10 @@ // Submitted by Angelo Gladding cnpy.gdn +// Codeberg e. V. : https://codeberg.org +// Submitted by Moritz Marquardt +codeberg.page + // CoDNS B.V. co.nl co.no @@ -11241,11 +10848,21 @@ // Submitted by Peter Thomassen dedyn.io +// Deta: https://www.deta.sh/ +// Submitted by Aavash Shrestha +deta.app +deta.dev + // Diher Solutions : https://diher.solutions // Submitted by Didi Hermawan *.rss.my.id *.diher.solutions +// Discord Inc : https://discord.com +// Submitted by Sahn Lam +discordsays.com +discordsez.com + // DNS Africa Ltd https://dns.business // Submitted by Calvin Browne jozi.biz @@ -11634,10 +11251,10 @@ // Submitted by Vladimir Dudr e4.cz -// eero : https://eero.com/ -// Submitted by Yue Kang -eero.online -eero-stage.online +// Easypanel : https://easypanel.io +// Submitted by Andrei Canta +easypanel.app +easypanel.host // Elementor : Elementor Ltd. // Submitted by Anton Barkan @@ -11653,11 +11270,20 @@ mytuleap.com tuleap-partners.com +// Encoretivity AB: https://encore.dev +// Submitted by André Eriksson +encr.app +encoreapi.com + // ECG Robotics, Inc: https://ecgrobotics.org // Submitted by onred.one staging.onred.one +// encoway GmbH : https://www.encoway.de +// Submitted by Marcel Daus +eu.encoway.cloud + // EU.org https://eu.org/ // Submitted by Pierre Beyssac eu.org @@ -11832,6 +11458,7 @@ // Fastly Inc. : http://www.fastly.com/ // Submitted by Fastly Security edgecompute.app +fastly-edge.com fastly-terrarium.com fastlylb.net map.fastlylb.net @@ -11843,6 +11470,10 @@ b.ssl.fastly.net global.ssl.fastly.net +// Fastmail : https://www.fastmail.com/ +// Submitted by Marc Bradshaw +*.user.fm + // FASTVPS EESTI OU : https://fastvps.ru/ // Submitted by Likhachev Vasiliy fastvps-server.com @@ -11861,8 +11492,6 @@ // FearWorks Media Ltd. : https://fearworksmedia.co.uk // submitted by Keith Fairley -couk.me -ukco.me conn.uk copro.uk hosp.uk @@ -11921,6 +11550,10 @@ // Submitted by Koen Rouwhorst framer.app framercanvas.com +framer.media +framer.photos +framer.website +framer.wiki // Frusky MEDIA&PR : https://www.frusky.de // Submitted by Victor Pupynin @@ -11966,10 +11599,22 @@ *.kunden.ortsinfo.at *.statics.cloud -// GDS : https://www.gov.uk/service-manual/operations/operating-servicegovuk-subdomains -// Submitted by David Illsley +// GDS : https://www.gov.uk/service-manual/technology/managing-domain-names +// Submitted by Stephen Ford +independent-commission.uk +independent-inquest.uk +independent-inquiry.uk +independent-panel.uk +independent-review.uk +public-inquiry.uk +royal-commission.uk +campaign.gov.uk service.gov.uk +// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk +// Submitted by Jamie Tanna +api.gov.uk + // Gehirn Inc. : https://www.gehirn.co.jp/ // Submitted by Kohei YOSHIDA gehirn.ne.jp @@ -12019,8 +11664,114 @@ shop.ro // GMO Pepabo, Inc. : https://pepabo.com/ -// Submitted by dojineko +// Submitted by Hosting Div lolipop.io +angry.jp +babyblue.jp +babymilk.jp +backdrop.jp +bambina.jp +bitter.jp +blush.jp +boo.jp +boy.jp +boyfriend.jp +but.jp +candypop.jp +capoo.jp +catfood.jp +cheap.jp +chicappa.jp +chillout.jp +chips.jp +chowder.jp +chu.jp +ciao.jp +cocotte.jp +coolblog.jp +cranky.jp +cutegirl.jp +daa.jp +deca.jp +deci.jp +digick.jp +egoism.jp +fakefur.jp +fem.jp +flier.jp +floppy.jp +fool.jp +frenchkiss.jp +girlfriend.jp +girly.jp +gloomy.jp +gonna.jp +greater.jp +hacca.jp +heavy.jp +her.jp +hiho.jp +hippy.jp +holy.jp +hungry.jp +icurus.jp +itigo.jp +jellybean.jp +kikirara.jp +kill.jp +kilo.jp +kuron.jp +littlestar.jp +lolipopmc.jp +lolitapunk.jp +lomo.jp +lovepop.jp +lovesick.jp +main.jp +mods.jp +mond.jp +mongolian.jp +moo.jp +namaste.jp +nikita.jp +nobushi.jp +noor.jp +oops.jp +parallel.jp +parasite.jp +pecori.jp +peewee.jp +penne.jp +pepper.jp +perma.jp +pigboat.jp +pinoko.jp +punyu.jp +pupu.jp +pussycat.jp +pya.jp +raindrop.jp +readymade.jp +sadist.jp +schoolbus.jp +secret.jp +staba.jp +stripper.jp +sub.jp +sunnyday.jp +thick.jp +tonkotsu.jp +under.jp +upper.jp +velvet.jp +verse.jp +versus.jp +vivian.jp +watson.jp +weblike.jp +whitesnow.jp +zombie.jp +heteml.net // GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ // Submitted by Tom Whitwell @@ -12142,6 +11893,10 @@ // Submitted by Niels Martignene goupile.fr +// Government of the Netherlands: https://www.government.nl +// Submitted by +gov.nl + // Group 53, LLC : https://www.group53.com // Submitted by Tyler Todd awsmppl.com @@ -12152,7 +11907,7 @@ günstigliefern.de // Hakaran group: http://hakaran.cz -// Submited by Arseniy Sokolov +// Submitted by Arseniy Sokolov fin.ci free.hr caa.li @@ -12187,20 +11942,25 @@ // Hibernating Rhinos // Submitted by Oren Eini -myravendb.com +ravendb.cloud ravendb.community ravendb.me development.run ravendb.run // home.pl S.A.: https://home.pl -// Submited by Krzysztof Wolski +// Submitted by Krzysztof Wolski homesklep.pl // Hong Kong Productivity Council: https://www.hkpc.org/ // Submitted by SECaaS Team secaas.hk +// Hoplix : https://www.hoplix.com +// Submitted by Danilo De Franco +hoplix.shop + + // HOSTBIP REGISTRY : https://www.hostbip.com/ // Submitted by Atanunu Igbunuroghene orx.biz @@ -12212,7 +11972,10 @@ ngo.ng edu.scot sch.so -org.yt + +// HostFly : https://www.ie.ua +// Submitted by Bohdan Dub +ie.ua // HostyHosting (hostyhosting.com) hostyhosting.io @@ -12230,6 +11993,11 @@ // Submitted by Hannu Aronsson iki.fi +// iliad italia: https://www.iliad.it +// Submitted by Marios Makassikis +ibxos.it +iliadboxos.it + // Impertrix Solutions : // Submitted by Zhixiang Zhao impertrixcdn.com @@ -12299,7 +12067,7 @@ pixolino.com // Internet-Pro, LLP: https://netangels.ru/ -// Submited by Vasiliy Sheredeko +// Submitted by Vasiliy Sheredeko na4u.ru // iopsys software solutions AB : https://iopsys.eu/ @@ -12310,9 +12078,11 @@ // Submitted by Matthew Hardeman ipifony.net -// IServ GmbH : https://iserv.eu -// Submitted by Kim-Alexander Brodowski +// IServ GmbH : https://iserv.de +// Submitted by Mario Hoberg +iservschule.de mein-iserv.de +schulplattform.de schulserver.de test-iserv.de iserv.dev @@ -12322,7 +12092,7 @@ iobb.net // Jelastic, Inc. : https://jelastic.com/ -// Submited by Ihor Kolodyuk +// Submitted by Ihor Kolodyuk mel.cloudlets.com.au cloud.interhostsolutions.be users.scale.virtualcloud.com.br @@ -12433,6 +12203,14 @@ kaas.gg khplay.nl +// Kakao : https://www.kakaocorp.com/ +// Submitted by JaeYoong Lee +ktistory.com + +// Kapsi : https://kapsi.fi +// Submitted by Tomi Juntunen +kapsi.fi + // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl keymachine.de @@ -12446,6 +12224,10 @@ // Submitted by Roy Keene knightpoint.systems +// KoobinEvent, SL: https://www.koobin.com +// Submitted by Iván Oliva +koobin.events + // KUROKU LTD : https://kuroku.ltd/ // Submitted by DisposaBoy oya.to @@ -12510,6 +12292,10 @@ // Submitted by Victor Velchev we.bs +// Localcert : https://localcert.dev +// Submitted by Lann Martin +*.user.localcert.dev + // localzone.xyz // Submitted by Kenny Niehage localzone.xyz @@ -12618,6 +12404,10 @@ miniserver.com memset.net +// Messerli Informatik AG : https://www.messerli.ch/ +// Submitted by Ruben Schmidmeister +messerli.app + // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Zdeněk Šustr *.cloud.metacentrum.cz @@ -12637,12 +12427,15 @@ co.pl // Microsoft Corporation : http://microsoft.com -// Submitted by Mitch Webster +// Submitted by Public Suffix List Admin *.azurecontainer.io azurewebsites.net azure-mobile.net cloudapp.net azurestaticapps.net +1.azurestaticapps.net +2.azurestaticapps.net +3.azurestaticapps.net centralus.azurestaticapps.net eastasia.azurestaticapps.net eastus2.azurestaticapps.net @@ -12695,24 +12488,9 @@ // Submitted by Paulus Schoutsen ui.nabu.casa -// Names.of.London : https://names.of.london/ -// Submitted by James Stevens or -pony.club -of.fashion -in.london -of.london -from.marketing -with.marketing -for.men -repair.men -and.mom -for.mom -for.one -under.one -for.sale -that.win -from.work -to.work +// Net at Work Gmbh : https://www.netatwork.de +// Submitted by Jan Jaeschke +cloud.nospamproxy.com // Netlify : https://www.netlify.com // Submitted by Jessica Parsons @@ -12724,7 +12502,19 @@ // ngrok : https://ngrok.com/ // Submitted by Alan Shreve +ngrok.app +ngrok-free.app +ngrok.dev +ngrok-free.dev ngrok.io +ap.ngrok.io +au.ngrok.io +eu.ngrok.io +in.ngrok.io +jp.ngrok.io +sa.ngrok.io +us.ngrok.io +ngrok.pizza // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ // Submitted by Nicholas Ford @@ -12742,7 +12532,10 @@ // Northflank Ltd. : https://northflank.com/ // Submitted by Marco Suter *.northflank.app +*.build.run *.code.run +*.database.run +*.migration.run // Noticeable : https://noticeable.io // Submitted by Laurent Pellegrino @@ -12873,11 +12666,6 @@ // Submitted by Konstantin Nosov stage.nodeart.io -// Nodum B.V. : https://nodum.io/ -// Submitted by Wietse Wind -nodum.co -nodum.io - // Nucleos Inc. : https://nucleos.com // Submitted by Piotr Zduniak pcloud.host @@ -12908,7 +12696,26 @@ // One.com: https://www.one.com/ // Submitted by Jacob Bunk Nielsen +123hjemmeside.dk +123hjemmeside.no +123homepage.it +123kotisivu.fi +123minsida.se +123miweb.es +123paginaweb.pt +123sait.ru +123siteweb.fr +123webseite.at +123webseite.de +123website.be +123website.ch +123website.lu +123website.nl service.one +simplesite.com +simplesite.com.br +simplesite.gr +simplesite.pl // One Fold Media : http://www.onefoldmedia.com/ // Submitted by Eddie Jones @@ -12930,8 +12737,12 @@ // Submitted by Yngve Pettersen operaunite.com +// Orange : https://www.orange.com +// Submitted by Alexandre Linte +tech.orange + // Oursky Limited : https://authgear.com/, https://skygear.io/ -// Submited by Authgear Team , Skygear Developer +// Submitted by Authgear Team , Skygear Developer authgear-staging.com authgearapps.com skygearapp.com @@ -13039,6 +12850,10 @@ // Submitted by Maximilian Schieder dyn53.io +// Porter : https://porter.run/ +// Submitted by Rudraksh MK +onporter.run + // Positive Codes Technology Company : http://co.bn/faq.html // Submitted by Zulfais co.bn @@ -13096,6 +12911,10 @@ // Submitted by Xavier De Cock qualifioapp.com +// Quality Unit: https://qualityunit.com +// Submitted by Vasyl Tsalko +ladesk.com + // QuickBackend: https://www.quickbackend.com // Submitted by Dani Biro qbuser.com @@ -13169,7 +12988,9 @@ onrender.com // Repl.it : https://repl.it -// Submitted by Mason Clayton +// Submitted by Lincoln Bergeson +firewalledreplit.co +id.firewalledreplit.co repl.co id.repl.co repl.run @@ -13200,6 +13021,10 @@ // Submitted by Jennifer Herting git-pages.rit.edu +// Rocky Enterprise Software Foundation : https://resf.org +// Submitted by Neil Hanlon +rocky.page + // Rusnames Limited: http://rusnames.ru/ // Submitted by Sergey Zotov биз.рус @@ -13213,6 +13038,62 @@ спб.рус я.рус +// SAKURA Internet Inc. : https://www.sakura.ad.jp/ +// Submitted by Internet Service Department +180r.com +dojin.com +sakuratan.com +sakuraweb.com +x0.com +2-d.jp +bona.jp +crap.jp +daynight.jp +eek.jp +flop.jp +halfmoon.jp +jeez.jp +matrix.jp +mimoza.jp +ivory.ne.jp +mail-box.ne.jp +mints.ne.jp +mokuren.ne.jp +opal.ne.jp +sakura.ne.jp +sumomo.ne.jp +topaz.ne.jp +netgamers.jp +nyanta.jp +o0o0.jp +rdy.jp +rgr.jp +rulez.jp +s3.isk01.sakurastorage.jp +s3.isk02.sakurastorage.jp +saloon.jp +sblo.jp +skr.jp +tank.jp +uh-oh.jp +undo.jp +rs.webaccel.jp +user.webaccel.jp +websozai.jp +xii.jp +squares.net +jpn.org +kirara.st +x0.to +from.tv +sakura.tv + +// Salesforce.com, Inc. https://salesforce.com/ +// Submitted by Michael Biven +*.builder.code.com +*.dev-builder.code.com +*.stg-builder.code.com + // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia sandcats.io @@ -13222,6 +13103,34 @@ logoip.de logoip.com +// Scaleway : https://www.scaleway.com/ +// Submitted by Rémy Léone +fr-par-1.baremetal.scw.cloud +fr-par-2.baremetal.scw.cloud +nl-ams-1.baremetal.scw.cloud +fnc.fr-par.scw.cloud +functions.fnc.fr-par.scw.cloud +k8s.fr-par.scw.cloud +nodes.k8s.fr-par.scw.cloud +s3.fr-par.scw.cloud +s3-website.fr-par.scw.cloud +whm.fr-par.scw.cloud +priv.instances.scw.cloud +pub.instances.scw.cloud +k8s.scw.cloud +k8s.nl-ams.scw.cloud +nodes.k8s.nl-ams.scw.cloud +s3.nl-ams.scw.cloud +s3-website.nl-ams.scw.cloud +whm.nl-ams.scw.cloud +k8s.pl-waw.scw.cloud +nodes.k8s.pl-waw.scw.cloud +s3.pl-waw.scw.cloud +s3-website.pl-waw.scw.cloud +scalebook.scw.cloud +smartlabeling.scw.cloud +dedibox.fr + // schokokeks.org GbR : https://schokokeks.org/ // Submitted by Hanno Böck schokokeks.net @@ -13329,6 +13238,13 @@ // Submitted by Dan Kozak vp4.me +// Snowflake Inc : https://www.snowflake.com/ +// Submitted by Faith Olapade +snowflake.app +privatelink.snowflake.app +streamlit.app +streamlitapp.com + // Snowplow Analytics : https://snowplowanalytics.com/ // Submitted by Ian Streeter try-snowplow.com @@ -13342,6 +13258,8 @@ stackhero-network.com // Staclar : https://staclar.com +// Submitted by Q Misell +musician.io // Submitted by Matthias Merkel novecore.site @@ -13440,25 +13358,28 @@ // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng -diskstation.me dscloud.biz -dscloud.me -dscloud.mobi +direct.quickconnect.cn dsmynas.com -dsmynas.net -dsmynas.org familyds.com -familyds.net -familyds.org +diskstation.me +dscloud.me i234.me myds.me synology.me +dscloud.mobi +dsmynas.net +familyds.net +dsmynas.org +familyds.org vpnplus.to direct.quickconnect.to // Tabit Technologies Ltd. : https://tabit.cloud/ // Submitted by Oren Agiv tabitorder.co.il +mytabit.co.il +mytabit.com // TAIFUN Software AG : http://taifun-software.de // Submitted by Bjoern Henke @@ -13476,9 +13397,14 @@ med.pl sopot.pl +// team.blue https://team.blue +// Submitted by Cedric Dubois +site.tb-hosting.com + // Teckids e.V. : https://www.teckids.org // Submitted by Dominik George -edugit.org +edugit.io +s3.teckids.org // Telebit : https://telebit.cloud // Submitted by AJ ONeal @@ -13486,10 +13412,6 @@ telebit.io *.telebit.xyz -// The Gwiddle Foundation : https://gwiddlefoundation.org.uk -// Submitted by Joshua Bayfield -gwiddle.co.uk - // Thingdust AG : https://thingdust.com/ // Submitted by Adrian Imboden *.firenet.ch @@ -13524,10 +13446,6 @@ bloxcms.com townnews-staging.com -// TradableBits: https://tradablebits.com -// Submitted by Dmitry Khrisanov dmitry@tradablebits.com -tbits.me - // TrafficPlex GmbH : https://www.trafficplex.de/ // Submitted by Phillipp Röll 12hp.at @@ -13556,6 +13474,10 @@ *.transurl.eu *.transurl.nl +// TransIP: https://www.transip.nl +// Submitted by Cedric Dubois +site.transip.me + // TuxFamily : http://tuxfamily.org // Submitted by TuxFamily administrators tuxfamily.org @@ -13576,6 +13498,14 @@ synology-diskstation.de synology-ds.de +// Typedream : https://typedream.com +// Submitted by Putri Karunia +typedream.app + +// Typeform : https://www.typeform.com +// Submitted by Sergi Ferriz +pro.typeform.com + // Uberspace : https://uberspace.de // Submitted by Moritz Werner uber.space @@ -13588,6 +13518,19 @@ ltd.hk inc.hk +// UK Intis Telecom LTD : https://it.com +// Submitted by ITComdomains +it.com + +// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ +// see also: whois -h whois.udr.org.yt help +// Submitted by Atanunu Igbunuroghene +name.pm +sch.tf +biz.wf +sch.wf +org.yt + // United Gameserver GmbH : https://united-gameserver.de // Submitted by Stefan Schwarz virtualuser.de @@ -13674,19 +13617,14 @@ // Submitted by Serhii Rostilo v.ua +// Vultr Objects : https://www.vultr.com/products/object-storage/ +// Submitted by Niels Maumenee +*.vultrobjects.com + // Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com // Submitted by Masayuki Note wafflecell.com -// WapBlog.ID : https://www.wapblog.id -// Submitted by Fajar Sodik -idnblogger.com -indowapblog.com -bloger.id -wblog.id -wbq.me -fastblog.net - // WebHare bv: https://www.webhare.com/ // Submitted by Arnold Hendriks *.webhare.dev @@ -13723,6 +13661,10 @@ panel.gg daemon.panel.gg +// Wizard Zines : https://wizardzines.com +// Submitted by Julia Evans +messwithdns.com + // WoltLab GmbH : https://www.woltlab.com // Submitted by Tim Düsterhus woltlab-demo.com diff -Nru openjdk-lts-11.0.20.1+1/make/data/publicsuffixlist/VERSION openjdk-lts-11.0.21+9/make/data/publicsuffixlist/VERSION --- openjdk-lts-11.0.20.1+1/make/data/publicsuffixlist/VERSION 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/data/publicsuffixlist/VERSION 2023-10-06 05:33:33.000000000 +0000 @@ -1,2 +1,2 @@ -Github: https://raw.githubusercontent.com/publicsuffix/list/3c213aab32b3c014f171b1673d4ce9b5cd72bf1c/public_suffix_list.dat -Date: 2021-11-27 +Github: https://raw.githubusercontent.com/publicsuffix/list/88467c960d6cdad2ca1623e892e5e17506bc269f/public_suffix_list.dat +Date: 2023-04-14 diff -Nru openjdk-lts-11.0.20.1+1/make/lib/Awt2dLibraries.gmk openjdk-lts-11.0.21+9/make/lib/Awt2dLibraries.gmk --- openjdk-lts-11.0.20.1+1/make/lib/Awt2dLibraries.gmk 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/make/lib/Awt2dLibraries.gmk 2023-10-06 05:33:33.000000000 +0000 @@ -527,6 +527,7 @@ E_END_OF_LOOP_CODE_NOT_REACHED, \ DISABLED_WARNINGS_microsoft := 4018 4267 4244 4312 4819, \ DISABLED_WARNINGS_gcc := implicit-fallthrough cast-function-type bad-function-cast, \ + DISABLED_WARNINGS_clang := missing-declarations, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ )) @@ -559,10 +560,12 @@ # hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later. LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc - HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing + HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing \ + array-bounds # 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+. HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \ - maybe-uninitialized class-memaccess unused-result extra noexcept-type + maybe-uninitialized class-memaccess unused-result extra noexcept-type expansion-to-defined HARFBUZZ_DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \ tautological-constant-out-of-range-compare int-to-pointer-cast \ undef missing-field-initializers deprecated-declarations c++11-narrowing range-loop-analysis diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/aarch64.ad openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/aarch64.ad --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/aarch64.ad 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/aarch64.ad 2023-10-06 05:33:33.000000000 +0000 @@ -971,6 +971,26 @@ V3, V3_H ); +// Class for 128 bit register v4 +reg_class v4_reg( + V4, V4_H +); + +// Class for 128 bit register v5 +reg_class v5_reg( + V5, V5_H +); + +// Class for 128 bit register v6 +reg_class v6_reg( + V6, V6_H +); + +// Class for 128 bit register v7 +reg_class v7_reg( + V7, V7_H +); + // Singleton class for condition codes reg_class int_flags(RFLAGS); @@ -4884,6 +4904,42 @@ interface(REG_INTER); %} +operand vRegD_V4() +%{ + constraint(ALLOC_IN_RC(v4_reg)); + match(RegD); + op_cost(0); + format %{ %} + interface(REG_INTER); +%} + +operand vRegD_V5() +%{ + constraint(ALLOC_IN_RC(v5_reg)); + match(RegD); + op_cost(0); + format %{ %} + interface(REG_INTER); +%} + +operand vRegD_V6() +%{ + constraint(ALLOC_IN_RC(v6_reg)); + match(RegD); + op_cost(0); + format %{ %} + interface(REG_INTER); +%} + +operand vRegD_V7() +%{ + constraint(ALLOC_IN_RC(v7_reg)); + match(RegD); + op_cost(0); + format %{ %} + interface(REG_INTER); +%} + // Flags register, used as output of signed compare instructions // note that on AArch64 we also use this register as the output for @@ -15390,14 +15446,17 @@ %} instruct string_indexofUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, - iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, - iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) + iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, + iRegINoSp tmp3, iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); - format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU)" %} + TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, + TEMP vtmp0, TEMP vtmp1, KILL cr); + format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UU) " + "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} ins_encode %{ __ string_indexof($str1$$Register, $str2$$Register, @@ -15411,14 +15470,17 @@ %} instruct string_indexofLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, - iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, - iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) + iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, + iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); - format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL)" %} + TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, + TEMP vtmp0, TEMP vtmp1, KILL cr); + format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (LL) " + "# KILL $str1 $cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} ins_encode %{ __ string_indexof($str1$$Register, $str2$$Register, @@ -15432,14 +15494,17 @@ %} instruct string_indexofUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2, - iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, - iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, rFlagsReg cr) + iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, iRegINoSp tmp3, + iRegINoSp tmp4, iRegINoSp tmp5, iRegINoSp tmp6, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, - TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, TEMP tmp6, KILL cr); - format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL)" %} + TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, + TEMP tmp6, TEMP vtmp0, TEMP vtmp1, KILL cr); + format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result (UL) " + "# KILL $str1 cnt1 $str2 $cnt2 $tmp1 $tmp2 $tmp3 $tmp4 $tmp5 $tmp6 V0-V1 cr" %} ins_encode %{ __ string_indexof($str1$$Register, $str2$$Register, @@ -15453,14 +15518,15 @@ %} instruct string_indexof_conUU(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, - immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, - iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) + immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, + iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); - format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU)" %} + format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UU) " + "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} ins_encode %{ int icnt2 = (int)$int_cnt2$$constant; @@ -15474,14 +15540,15 @@ %} instruct string_indexof_conLL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, - immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, - iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) + immI_le_4 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, + iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); - format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL)" %} + format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (LL) " + "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} ins_encode %{ int icnt2 = (int)$int_cnt2$$constant; @@ -15495,14 +15562,15 @@ %} instruct string_indexof_conUL(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, - immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, iRegINoSp tmp2, - iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) + immI_1 int_cnt2, iRegI_R0 result, iRegINoSp tmp1, + iRegINoSp tmp2, iRegINoSp tmp3, iRegINoSp tmp4, rFlagsReg cr) %{ predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL); match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr); - format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL)" %} + format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result (UL) " + "# KILL $str1 $cnt1 $str2 $tmp1 $tmp2 $tmp3 $tmp4 cr" %} ins_encode %{ int icnt2 = (int)$int_cnt2$$constant; @@ -15567,13 +15635,17 @@ instruct array_equalsB(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, + vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, iRegP_R10 tmp, rFlagsReg cr) %{ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); match(Set result (AryEq ary1 ary2)); - effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); + effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, + TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, + TEMP vtmp6, TEMP vtmp7, KILL cr); - format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} + format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} ins_encode %{ address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, @@ -15588,13 +15660,17 @@ instruct array_equalsC(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result, iRegP_R3 tmp1, iRegP_R4 tmp2, iRegP_R5 tmp3, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, + vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, vRegD_V7 vtmp7, iRegP_R10 tmp, rFlagsReg cr) %{ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); match(Set result (AryEq ary1 ary2)); - effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr); + effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, TEMP tmp1, TEMP tmp2, TEMP tmp3, + TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, + TEMP vtmp6, TEMP vtmp7, KILL cr); - format %{ "Array Equals $ary1,ary2 -> $result // KILL $tmp" %} + format %{ "Array Equals $ary1,ary2 -> $result # KILL $ary1 $ary2 $tmp $tmp1 $tmp2 $tmp3 V0-V7 cr" %} ins_encode %{ address tpc = __ arrays_equals($ary1$$Register, $ary2$$Register, $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, @@ -15624,35 +15700,40 @@ // fast char[] to byte[] compression instruct string_compress(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, - vRegD_V0 tmp1, vRegD_V1 tmp2, - vRegD_V2 tmp3, vRegD_V3 tmp4, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, + vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, iRegI_R0 result, rFlagsReg cr) %{ match(Set result (StrCompressedCopy src (Binary dst len))); - effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); + effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, + USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); - format %{ "String Compress $src,$dst -> $result // KILL R1, R2, R3, R4" %} + format %{ "String Compress $src,$dst -> $result # KILL $src $dst $len V0-V5 cr" %} ins_encode %{ __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, - $tmp1$$FloatRegister, $tmp2$$FloatRegister, - $tmp3$$FloatRegister, $tmp4$$FloatRegister, + $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, + $vtmp4$$FloatRegister, $vtmp5$$FloatRegister, $result$$Register); %} ins_pipe( pipe_slow ); %} // fast byte[] to char[] inflation -instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, - vRegD_V0 tmp1, vRegD_V1 tmp2, vRegD_V2 tmp3, iRegP_R3 tmp4, rFlagsReg cr) +instruct string_inflate(Universe dummy, iRegP_R0 src, iRegP_R1 dst, iRegI_R2 len, iRegP_R3 tmp, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, vRegD_V3 vtmp3, + vRegD_V4 vtmp4, vRegD_V5 vtmp5, vRegD_V6 vtmp6, rFlagsReg cr) %{ match(Set dummy (StrInflatedCopy src (Binary dst len))); - effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); + effect(TEMP vtmp0, TEMP vtmp1, TEMP vtmp2, TEMP vtmp3, + TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP tmp, + USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); - format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} + format %{ "String Inflate $src,$dst # KILL $tmp $src $dst $len V0-V6 cr" %} ins_encode %{ address tpc = __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, - $tmp1$$FloatRegister, $tmp2$$FloatRegister, - $tmp3$$FloatRegister, $tmp4$$Register); + $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $tmp$$Register); if (tpc == NULL) { ciEnv::current()->record_failure("CodeCache is full"); return; @@ -15663,19 +15744,20 @@ // encode char[] to byte[] in ISO_8859_1 instruct encode_iso_array(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, - vRegD_V0 Vtmp1, vRegD_V1 Vtmp2, - vRegD_V2 Vtmp3, vRegD_V3 Vtmp4, + vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2, + vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5, iRegI_R0 result, rFlagsReg cr) %{ match(Set result (EncodeISOArray src (Binary dst len))); - effect(USE_KILL src, USE_KILL dst, USE_KILL len, - KILL Vtmp1, KILL Vtmp2, KILL Vtmp3, KILL Vtmp4, KILL cr); + effect(USE_KILL src, USE_KILL dst, USE_KILL len, KILL vtmp0, KILL vtmp1, + KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL cr); - format %{ "Encode array $src,$dst,$len -> $result" %} + format %{ "Encode array $src,$dst,$len -> $result # KILL $src $dst $len V0-V5 cr" %} ins_encode %{ __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, - $result$$Register, $Vtmp1$$FloatRegister, $Vtmp2$$FloatRegister, - $Vtmp3$$FloatRegister, $Vtmp4$$FloatRegister); + $result$$Register, $vtmp0$$FloatRegister, $vtmp1$$FloatRegister, + $vtmp2$$FloatRegister, $vtmp3$$FloatRegister, + $vtmp4$$FloatRegister, $vtmp5$$FloatRegister); %} ins_pipe( pipe_class_memory ); %} diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/frame_aarch64.cpp openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/frame_aarch64.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/frame_aarch64.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/frame_aarch64.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -542,7 +542,7 @@ // first the method - Method* m = *interpreter_frame_method_addr(); + Method* m = safe_interpreter_frame_method(); // validate the method we'd find in this potential sender if (!Method::is_valid_method(m)) return false; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -4332,6 +4332,7 @@ typedef void (MacroAssembler::* chr_insn)(Register Rt, const Address &adr); // Search for str1 in str2 and return index or -1 +// Clobbers: rscratch1, rscratch2, rflags. May also clobber v0-v1, when icnt1==-1. void MacroAssembler::string_indexof(Register str2, Register str1, Register cnt2, Register cnt1, Register tmp1, Register tmp2, @@ -5123,6 +5124,8 @@ return pc(); } +// Clobbers: rscratch1, rscratch2, rflags +// May also clobber v0-v7 when (!UseSimpleArrayEquals && UseSIMDForArrayEquals) address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3, Register tmp4, Register tmp5, Register result, Register cnt1, int elem_size) { @@ -5615,10 +5618,13 @@ // Intrinsic for sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray and // java/lang/StringUTF16.compress. +// +// Clobbers: src, dst, res, rscratch1, rscratch2, rflags void MacroAssembler::encode_iso_array(Register src, Register dst, - Register len, Register result, - FloatRegister Vtmp1, FloatRegister Vtmp2, - FloatRegister Vtmp3, FloatRegister Vtmp4) + Register len, Register result, + FloatRegister Vtmp1, FloatRegister Vtmp2, + FloatRegister Vtmp3, FloatRegister Vtmp4, + FloatRegister Vtmp5, FloatRegister Vtmp6) { Label DONE, SET_RESULT, NEXT_32, NEXT_32_PRFM, LOOP_8, NEXT_8, LOOP_1, NEXT_1, NEXT_32_START, NEXT_32_PRFM_START; @@ -5641,13 +5647,13 @@ ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); BIND(NEXT_32_PRFM_START); prfm(Address(src, SoftwarePrefetchHintDistance)); - orr(v4, T16B, Vtmp1, Vtmp2); - orr(v5, T16B, Vtmp3, Vtmp4); + orr(Vtmp5, T16B, Vtmp1, Vtmp2); + orr(Vtmp6, T16B, Vtmp3, Vtmp4); uzp1(Vtmp1, T16B, Vtmp1, Vtmp2); uzp1(Vtmp3, T16B, Vtmp3, Vtmp4); - uzp2(v5, T16B, v4, v5); // high bytes - umov(tmp2, v5, D, 1); - fmovd(tmp1, v5); + uzp2(Vtmp6, T16B, Vtmp5, Vtmp6); // high bytes + umov(tmp2, Vtmp6, D, 1); + fmovd(tmp1, Vtmp6); orr(tmp1, tmp1, tmp2); cbnz(tmp1, LOOP_8); stpq(Vtmp1, Vtmp3, dst); @@ -5666,8 +5672,8 @@ ld1(Vtmp1, Vtmp2, Vtmp3, Vtmp4, T8H, src); } prfm(Address(src, SoftwarePrefetchHintDistance)); - uzp1(v4, T16B, Vtmp1, Vtmp2); - uzp1(v5, T16B, Vtmp3, Vtmp4); + uzp1(Vtmp5, T16B, Vtmp1, Vtmp2); + uzp1(Vtmp6, T16B, Vtmp3, Vtmp4); orr(Vtmp1, T16B, Vtmp1, Vtmp2); orr(Vtmp3, T16B, Vtmp3, Vtmp4); uzp2(Vtmp1, T16B, Vtmp1, Vtmp3); // high bytes @@ -5675,7 +5681,7 @@ fmovd(tmp1, Vtmp1); orr(tmp1, tmp1, tmp2); cbnz(tmp1, LOOP_8); - stpq(v4, v5, dst); + stpq(Vtmp5, Vtmp6, dst); sub(len, len, 32); add(dst, dst, 32); add(src, src, 64); @@ -5720,6 +5726,7 @@ // Inflate byte[] array to char[]. +// Clobbers: src, dst, len, rflags, rscratch1, v0-v6 address MacroAssembler::byte_array_inflate(Register src, Register dst, Register len, FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, Register tmp4) { @@ -5828,9 +5835,10 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register len, FloatRegister tmp1Reg, FloatRegister tmp2Reg, FloatRegister tmp3Reg, FloatRegister tmp4Reg, + FloatRegister tmp5Reg, FloatRegister tmp6Reg, Register result) { encode_iso_array(src, dst, len, result, - tmp1Reg, tmp2Reg, tmp3Reg, tmp4Reg); + tmp1Reg, tmp2Reg, tmp3Reg, tmp4Reg, tmp5Reg, tmp6Reg); cmp(len, zr); csel(result, result, zr, EQ); } diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -1245,12 +1245,14 @@ void char_array_compress(Register src, Register dst, Register len, FloatRegister tmp1Reg, FloatRegister tmp2Reg, FloatRegister tmp3Reg, FloatRegister tmp4Reg, + FloatRegister tmp5Reg, FloatRegister tmp6Reg, Register result); void encode_iso_array(Register src, Register dst, Register len, Register result, FloatRegister Vtmp1, FloatRegister Vtmp2, - FloatRegister Vtmp3, FloatRegister Vtmp4); + FloatRegister Vtmp3, FloatRegister Vtmp4, + FloatRegister Vtmp5, FloatRegister Vtmp6); void string_indexof(Register str1, Register str2, Register cnt1, Register cnt2, Register tmp1, Register tmp2, diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -4118,6 +4118,7 @@ // result = r0 - return value. Already contains "false" // cnt1 = r10 - amount of elements left to check, reduced by wordSize // r3-r5 are reserved temporary registers + // Clobbers: v0-v7 when UseSIMDForArrayEquals, rscratch1, rscratch2 address generate_large_array_equals() { Register a1 = r1, a2 = r2, result = r0, cnt1 = r10, tmp1 = rscratch1, tmp2 = rscratch2, tmp3 = r3, tmp4 = r4, tmp5 = r5, tmp6 = r11, @@ -4522,6 +4523,8 @@ // R2 = cnt1 // R3 = str1 // R4 = cnt2 + // Clobbers: rscratch1, rscratch2, v0, v1, rflags + // // This generic linear code use few additional ideas, which makes it faster: // 1) we can safely keep at least 1st register of pattern(since length >= 8) // in order to skip initial loading(help in systems with 1 ld pipeline) @@ -4836,6 +4839,7 @@ // R3 = len >> 3 // V0 = 0 // v1 = loaded 8 bytes + // Clobbers: r0, r1, r3, rscratch1, rflags, v0-v6 address generate_large_byte_array_inflate() { __ align(CodeEntryAlignment); StubCodeMark mark(this, "StubRoutines", "large_byte_array_inflate"); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/arm/frame_arm.cpp openjdk-lts-11.0.21+9/src/hotspot/cpu/arm/frame_arm.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/arm/frame_arm.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/arm/frame_arm.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -497,7 +497,7 @@ // first the method - Method* m = *interpreter_frame_method_addr(); + Method* m = safe_interpreter_frame_method(); // validate the method we'd find in this potential sender if (!Method::is_valid_method(m)) return false; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/ppc/frame_ppc.cpp openjdk-lts-11.0.21+9/src/hotspot/cpu/ppc/frame_ppc.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/ppc/frame_ppc.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/ppc/frame_ppc.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -302,7 +302,7 @@ // first the method - Method* m = *interpreter_frame_method_addr(); + Method* m = safe_interpreter_frame_method(); // validate the method we'd find in this potential sender if (!Method::is_valid_method(m)) return false; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/cpu/x86/frame_x86.cpp openjdk-lts-11.0.21+9/src/hotspot/cpu/x86/frame_x86.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/cpu/x86/frame_x86.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/cpu/x86/frame_x86.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -523,7 +523,7 @@ // do some validation of frame elements // first the method - Method* m = *interpreter_frame_method_addr(); + Method* m = safe_interpreter_frame_method(); // validate the method we'd find in this potential sender if (!Method::is_valid_method(m)) return false; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/os/linux/os_linux.cpp openjdk-lts-11.0.21+9/src/hotspot/os/linux/os_linux.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/os/linux/os_linux.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/os/linux/os_linux.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -835,6 +835,106 @@ return 0; } +// On Linux, glibc places static TLS blocks (for __thread variables) on +// the thread stack. This decreases the stack size actually available +// to threads. +// +// For large static TLS sizes, this may cause threads to malfunction due +// to insufficient stack space. This is a well-known issue in glibc: +// http://sourceware.org/bugzilla/show_bug.cgi?id=11787. +// +// As a workaround, we call a private but assumed-stable glibc function, +// __pthread_get_minstack() to obtain the minstack size and derive the +// static TLS size from it. We then increase the user requested stack +// size by this TLS size. The same function is used to determine whether +// adjustStackSizeForGuardPages() needs to be true. +// +// Due to compatibility concerns, this size adjustment is opt-in and +// controlled via AdjustStackSizeForTLS. +typedef size_t (*GetMinStack)(const pthread_attr_t *attr); + +GetMinStack _get_minstack_func = NULL; // Initialized via os::init_2() + +// Returns the size of the static TLS area glibc puts on thread stacks. +// The value is cached on first use, which occurs when the first thread +// is created during VM initialization. +static size_t get_static_tls_area_size(const pthread_attr_t *attr) { + size_t tls_size = 0; + if (_get_minstack_func != NULL) { + // Obtain the pthread minstack size by calling __pthread_get_minstack. + size_t minstack_size = _get_minstack_func(attr); + + // Remove non-TLS area size included in minstack size returned + // by __pthread_get_minstack() to get the static TLS size. + // If adjustStackSizeForGuardPages() is true, minstack size includes + // guard_size. Otherwise guard_size is automatically added + // to the stack size by pthread_create and is no longer included + // in minstack size. In both cases, the guard_size is taken into + // account, so there is no need to adjust the result for that. + // + // Although __pthread_get_minstack() is a private glibc function, + // it is expected to have a stable behavior across future glibc + // versions while glibc still allocates the static TLS blocks off + // the stack. Following is glibc 2.28 __pthread_get_minstack(): + // + // size_t + // __pthread_get_minstack (const pthread_attr_t *attr) + // { + // return GLRO(dl_pagesize) + __static_tls_size + PTHREAD_STACK_MIN; + // } + // + // + // The following 'minstack_size > os::vm_page_size() + PTHREAD_STACK_MIN' + // if check is done for precaution. + if (minstack_size > (size_t)os::vm_page_size() + PTHREAD_STACK_MIN) { + tls_size = minstack_size - (size_t)os::vm_page_size() - PTHREAD_STACK_MIN; + } + } + + log_info(os, thread)("Stack size adjustment for TLS is " SIZE_FORMAT, + tls_size); + return tls_size; +} + +// In glibc versions prior to 2.27 the guard size mechanism +// was not implemented properly. The POSIX standard requires adding +// the size of the guard pages to the stack size, instead glibc +// took the space out of 'stacksize'. Thus we need to adapt the requested +// stack_size by the size of the guard pages to mimic proper behaviour. +// The fix in glibc 2.27 has now been backported to numerous earlier +// glibc versions so we need to do a dynamic runtime check. +static bool _adjustStackSizeForGuardPages = true; +bool os::Linux::adjustStackSizeForGuardPages() { + return _adjustStackSizeForGuardPages; +} + +// Dummy decl as substitute for cmdline parameter. TLS not in jdk11. +static const bool AdjustStackSizeForTLS = false; + +#if defined(__GLIBC__) +static void init_adjust_stacksize_for_guard_pages() { + assert(_get_minstack_func == NULL, "initialization error"); + _get_minstack_func =(GetMinStack)dlsym(RTLD_DEFAULT, "__pthread_get_minstack"); + log_info(os, thread)("Lookup of __pthread_get_minstack %s", + _get_minstack_func == NULL ? "failed" : "succeeded"); + + if (_get_minstack_func != NULL) { + pthread_attr_t attr; + pthread_attr_init(&attr); + size_t min_stack = _get_minstack_func(&attr); + size_t guard = 16 * K; // Actual value doesn't matter as it is not examined + pthread_attr_setguardsize(&attr, guard); + size_t min_stack2 = _get_minstack_func(&attr); + pthread_attr_destroy(&attr); + // If the minimum stack size changed when we added the guard page space + // then we need to perform the adjustment. + _adjustStackSizeForGuardPages = (min_stack2 != min_stack); + log_info(os)("Glibc stack size guard page adjustment is %sneeded", + _adjustStackSizeForGuardPages ? "" : "not "); + } +} +#endif // GLIBC + bool os::create_thread(Thread* thread, ThreadType thr_type, size_t req_stack_size) { assert(thread->osthread() == NULL, "caller responsible"); @@ -860,16 +960,24 @@ // Calculate stack size if it's not specified by caller. size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); - // In the Linux NPTL pthread implementation the guard size mechanism - // is not implemented properly. The posix standard requires adding - // the size of the guard pages to the stack size, instead Linux - // takes the space out of 'stacksize'. Thus we adapt the requested - // stack_size by the size of the guard pages to mimick proper - // behaviour. However, be careful not to end up with a size - // of zero due to overflow. Don't add the guard page in that case. size_t guard_size = os::Linux::default_guard_size(thr_type); - if (stack_size <= SIZE_MAX - guard_size) { - stack_size += guard_size; + // Configure glibc guard page. Must happen before calling + // get_static_tls_area_size(), which uses the guard_size. + pthread_attr_setguardsize(&attr, guard_size); + + // Apply stack size adjustments if needed. However, be careful not to end up + // with a size of zero due to overflow. Don't add the adjustment in that case. + size_t stack_adjust_size = 0; + if (AdjustStackSizeForTLS) { + // Adjust the stack_size for on-stack TLS - see get_static_tls_area_size(). + stack_adjust_size += get_static_tls_area_size(&attr); + } else if (os::Linux::adjustStackSizeForGuardPages()) { + stack_adjust_size += guard_size; + } + + stack_adjust_size = align_up(stack_adjust_size, os::vm_page_size()); + if (stack_size <= SIZE_MAX - stack_adjust_size) { + stack_size += stack_adjust_size; } assert(is_aligned(stack_size, os::vm_page_size()), "stack_size not aligned"); @@ -1005,8 +1113,10 @@ // and save the caller's signal mask os::Linux::hotspot_sigmask(thread); - log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").", - os::current_thread_id(), (uintx) pthread_self()); + log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT + ", stack: " PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k) ).", + os::current_thread_id(), (uintx) pthread_self(), + p2i(thread->stack_base()), p2i(thread->stack_end()), thread->stack_size() / K); return true; } @@ -1421,7 +1531,7 @@ // Note, that some kernels may support the current thread // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks // returned by the pthread_getcpuclockid(). - // If the fast Posix clocks are supported then the sys_clock_getres() + // If the fast POSIX clocks are supported then the clock_getres() // must return at least tp.tv_sec == 0 which means a resolution // better than 1 sec. This is extra check for reliability. @@ -5518,6 +5628,11 @@ log_info(os)("HotSpot is running with %s, %s", Linux::libc_version(), Linux::libpthread_version()); +#ifdef __GLIBC__ + // Check if we need to adjust the stack size for glibc guard pages. + init_adjust_stacksize_for_guard_pages(); +#endif + if (UseNUMA) { if (!Linux::libnuma_init()) { UseNUMA = false; @@ -6410,9 +6525,9 @@ // // ** P1 (aka bottom) and size (P2 = P1 - size) are the address and stack size // returned from pthread_attr_getstack(). -// ** Due to NPTL implementation error, linux takes the glibc guard page out -// of the stack size given in pthread_attr. We work around this for -// threads created by the VM. (We adapt bottom to be P1 and size accordingly.) +// ** If adjustStackSizeForGuardPages() is true the guard pages have been taken +// out of the stack size given in pthread_attr. We work around this for +// threads created by the VM. We adjust bottom to be P1 and size accordingly. // #ifndef ZERO static void current_stack_region(address * bottom, size_t * size) { @@ -6439,14 +6554,15 @@ fatal("Cannot locate current stack attributes!"); } - // Work around NPTL stack guard error. - size_t guard_size = 0; - rslt = pthread_attr_getguardsize(&attr, &guard_size); - if (rslt != 0) { - fatal("pthread_attr_getguardsize failed with error = %d", rslt); - } - *bottom += guard_size; - *size -= guard_size; + if (os::Linux::adjustStackSizeForGuardPages()) { + size_t guard_size = 0; + rslt = pthread_attr_getguardsize(&attr, &guard_size); + if (rslt != 0) { + fatal("pthread_attr_getguardsize failed with error = %d", rslt); + } + *bottom += guard_size; + *size -= guard_size; + } pthread_attr_destroy(&attr); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/os/linux/os_linux.hpp openjdk-lts-11.0.21+9/src/hotspot/os/linux/os_linux.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/os/linux/os_linux.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/os/linux/os_linux.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -198,6 +198,8 @@ // Return default guard size for the specified thread type static size_t default_guard_size(os::ThreadType thr_type); + static bool adjustStackSizeForGuardPages(); // See comments in os_linux.cpp + static void capture_initial_stack(size_t max_size); // Stack overflow handling diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/os/posix/os_posix.cpp openjdk-lts-11.0.21+9/src/hotspot/os/posix/os_posix.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/os/posix/os_posix.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/os/posix/os_posix.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1429,8 +1429,8 @@ int detachstate = 0; pthread_attr_getstacksize(attr, &stack_size); pthread_attr_getguardsize(attr, &guard_size); - // Work around linux NPTL implementation error, see also os::create_thread() in os_linux.cpp. - LINUX_ONLY(stack_size -= guard_size); + // Work around glibc stack guard issue, see os::create_thread() in os_linux.cpp. + LINUX_ONLY(if (os::Linux::adjustStackSizeForGuardPages()) stack_size -= guard_size;) pthread_attr_getdetachstate(attr, &detachstate); jio_snprintf(buf, buflen, "stacksize: " SIZE_FORMAT "k, guardsize: " SIZE_FORMAT "k, %s", stack_size / 1024, guard_size / 1024, diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/c1/c1_LinearScan.cpp openjdk-lts-11.0.21+9/src/hotspot/share/c1/c1_LinearScan.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/c1/c1_LinearScan.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/c1/c1_LinearScan.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1947,6 +1947,14 @@ // interval at the throwing instruction must be searched using the operands // of the phi function Value from_value = phi->operand_at(handler->phi_operand()); + if (from_value == NULL) { + // We have reached here in a kotlin application running with JVMTI + // capability "can_access_local_variables". + // The illegal state is not yet propagated to this phi. Do it here. + phi->make_illegal(); + // We can skip the illegal phi edge. + return; + } // with phi functions it can happen that the same from_value is used in // multiple mappings, so notify move-resolver that this is allowed diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/altHashing.cpp openjdk-lts-11.0.21+9/src/hotspot/share/classfile/altHashing.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/altHashing.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/classfile/altHashing.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * 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,9 +31,7 @@ /* SipHash reference C implementation - Copyright (c) 2012-2021 Jean-Philippe Aumasson - - Copyright (c) 2012-2014 Daniel J. Bernstein + Copyright (c) 2016 Jean-Philippe Aumasson To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/dictionary.cpp openjdk-lts-11.0.21+9/src/hotspot/share/classfile/dictionary.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/dictionary.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/classfile/dictionary.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -208,6 +208,7 @@ if (lt.is_enabled()) { LogStream ls(lt); print_count(&ls); + ls.cr(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/dictionary.hpp openjdk-lts-11.0.21+9/src/hotspot/share/classfile/dictionary.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/dictionary.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/classfile/dictionary.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -195,7 +195,7 @@ current = current->_next) { count++; } - st->print_cr("pd set count = #%d", count); + st->print("pd set count = #%d", count); } void verify(); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/loaderConstraints.cpp openjdk-lts-11.0.21+9/src/hotspot/share/classfile/loaderConstraints.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/loaderConstraints.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/classfile/loaderConstraints.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -189,6 +189,7 @@ bool LoaderConstraintTable::add_entry(Symbol* class_name, InstanceKlass* klass1, Handle class_loader1, InstanceKlass* klass2, Handle class_loader2) { + LogTarget(Info, class, loader, constraints) lt; if (klass1 != NULL && klass2 != NULL) { if (klass1 == klass2) { @@ -242,9 +243,8 @@ p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass)); p->set_loader(0, class_loader1()); p->set_loader(1, class_loader2()); - p->set_klass(klass); - p->set_next(bucket(index)); - set_entry(index, p); + Hashtable::add_entry(index, p); + if (lt.is_enabled()) { ResourceMark rm; lt.print("adding new constraint for name: %s, loader[0]: %s," @@ -478,13 +478,15 @@ probe != NULL; probe = probe->next()) { st->print("%4d: ", cindex); - probe->name()->print_on(st); - st->print(" , loaders:"); + st->print("Symbol: %s loaders:", probe->name()->as_C_string()); for (int n = 0; n < probe->num_loaders(); n++) { + st->cr(); + st->print(" "); probe->loader_data(n)->print_value_on(st); - st->print(", "); } st->cr(); } } } + +void LoaderConstraintTable::print() const { print_on(tty); } diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/loaderConstraints.hpp openjdk-lts-11.0.21+9/src/hotspot/share/classfile/loaderConstraints.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/classfile/loaderConstraints.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/classfile/loaderConstraints.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -79,6 +79,7 @@ void purge_loader_constraints(); void verify(PlaceholderTable* placeholders); + void print() const; void print_on(outputStream* st) const; }; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp openjdk-lts-11.0.21+9/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -5788,6 +5788,9 @@ if (!_virtual_space.initialize(rs, rs.size())) { fatal("Not enough swap for expanded marking stack"); } + // Record NMT memory type + MemTracker::record_virtual_memory_type(rs.base(), mtGC); + _base = (oop*)(_virtual_space.low()); _index = 0; _capacity = new_capacity; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp openjdk-lts-11.0.21+9/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -506,6 +506,7 @@ while (*entry != NULL) { oop* p = (oop*)(*entry)->obj_addr(); if (cl->is_alive(*p)) { + typeArrayOop value = (typeArrayOop)*p; cl->keep_alive(p); if (is_resizing()) { // We are resizing the table, transfer entry to the new table @@ -517,7 +518,6 @@ // at this point since we don't have exclusive access to all // destination partitions. finish_rehash() will do a single // threaded transfer of all entries. - typeArrayOop value = (typeArrayOop)*p; bool latin1 = (*entry)->latin1(); unsigned int hash = hash_code(value, latin1); (*entry)->set_hash(hash); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/interpreter/interpreterRuntime.cpp openjdk-lts-11.0.21+9/src/hotspot/share/interpreter/interpreterRuntime.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/interpreter/interpreterRuntime.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/interpreter/interpreterRuntime.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -854,24 +854,17 @@ CallInfo info; constantPoolHandle pool(thread, last_frame.method()->constants()); + methodHandle resolved_method; + { JvmtiHideSingleStepping jhss(thread); LinkResolver::resolve_invoke(info, receiver, pool, last_frame.get_index_u2_cpcache(bytecode), bytecode, CHECK); - if (JvmtiExport::can_hotswap_or_post_breakpoint()) { - int retry_count = 0; - while (info.resolved_method()->is_old()) { - // It is very unlikely that method is redefined more than 100 times - // in the middle of resolve. If it is looping here more than 100 times - // means then there could be a bug here. - guarantee((retry_count++ < 100), - "Could not resolve to latest version of redefined method"); - // method is redefined in the middle of resolve so re-try. - LinkResolver::resolve_invoke(info, receiver, pool, - last_frame.get_index_u2_cpcache(bytecode), bytecode, - CHECK); - } + if (JvmtiExport::can_hotswap_or_post_breakpoint() && info.resolved_method()->is_old()) { + resolved_method = methodHandle(thread, info.resolved_method()->get_new_method()); + } else { + resolved_method = info.resolved_method(); } } // end JvmtiHideSingleStepping @@ -881,22 +874,20 @@ #ifdef ASSERT if (bytecode == Bytecodes::_invokeinterface) { - if (info.resolved_method()->method_holder() == - SystemDictionary::Object_klass()) { + if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { // NOTE: THIS IS A FIX FOR A CORNER CASE in the JVM spec // (see also CallInfo::set_interface for details) assert(info.call_kind() == CallInfo::vtable_call || info.call_kind() == CallInfo::direct_call, ""); - methodHandle rm = info.resolved_method(); - assert(rm->is_final() || info.has_vtable_index(), + assert(resolved_method->is_final() || info.has_vtable_index(), "should have been set already"); - } else if (!info.resolved_method()->has_itable_index()) { + } else if (!resolved_method->has_itable_index()) { // Resolved something like CharSequence.toString. Use vtable not itable. assert(info.call_kind() != CallInfo::itable_call, ""); } else { // Setup itable entry assert(info.call_kind() == CallInfo::itable_call, ""); - int index = info.resolved_method()->itable_index(); + int index = resolved_method->itable_index(); assert(info.itable_index() == index, ""); } } else if (bytecode == Bytecodes::_invokespecial) { @@ -916,20 +907,20 @@ case CallInfo::direct_call: cp_cache_entry->set_direct_call( bytecode, - info.resolved_method(), + resolved_method, sender->is_interface()); break; case CallInfo::vtable_call: cp_cache_entry->set_vtable_call( bytecode, - info.resolved_method(), + resolved_method, info.vtable_index()); break; case CallInfo::itable_call: cp_cache_entry->set_itable_call( bytecode, info.resolved_klass(), - info.resolved_method(), + resolved_method, info.itable_index()); break; default: ShouldNotReachHere(); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/memory/metaspace.cpp openjdk-lts-11.0.21+9/src/hotspot/share/memory/metaspace.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/memory/metaspace.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/memory/metaspace.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -758,6 +758,7 @@ out->print_cr(" Non-Class:"); } Metaspace::space_list()->print_on(out, scale); + out->cr(); if (Metaspace::using_class_space()) { out->print_cr(" Class:"); Metaspace::class_space_list()->print_on(out, scale); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/memory/metaspaceShared.cpp openjdk-lts-11.0.21+9/src/hotspot/share/memory/metaspaceShared.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/memory/metaspaceShared.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/memory/metaspaceShared.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1344,12 +1344,6 @@ FileMapInfo::check_nonempty_dir_in_shared_path_table(); NOT_PRODUCT(SystemDictionary::verify();) - // The following guarantee is meant to ensure that no loader constraints - // exist yet, since the constraints table is not shared. This becomes - // more important now that we don't re-initialize vtables/itables for - // shared classes at runtime, where constraints were previously created. - guarantee(SystemDictionary::constraints()->number_of_entries() == 0, - "loader constraints are not saved"); guarantee(SystemDictionary::placeholders()->number_of_entries() == 0, "placeholders are not saved"); // Revisit and implement this if we prelink method handle call sites: diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/klass.cpp openjdk-lts-11.0.21+9/src/hotspot/share/oops/klass.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/klass.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/oops/klass.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/dictionary.hpp" -#include "classfile/javaClasses.hpp" +#include "classfile/javaClasses.inline.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "gc/shared/collectedHeap.inline.hpp" @@ -735,7 +735,7 @@ } if (java_mirror_no_keepalive() != NULL) { - guarantee(oopDesc::is_oop(java_mirror_no_keepalive()), "should be instance"); + guarantee(java_lang_Class::is_instance(java_mirror_no_keepalive()), "should be instance"); } } diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/klass.hpp openjdk-lts-11.0.21+9/src/hotspot/share/oops/klass.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/klass.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/oops/klass.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -269,9 +269,8 @@ // Both mirrors are on the ClassLoaderData::_handles list already so no // barriers are needed. void set_java_mirror_handle(OopHandle mirror) { _java_mirror = mirror; } - OopHandle java_mirror_handle() const { - return _java_mirror; - } + OopHandle java_mirror_handle() const { return _java_mirror; } + void swap_java_mirror_handle(OopHandle& mirror) { _java_mirror.swap(mirror); } // modifier flags jint modifier_flags() const { return _modifier_flags; } diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/method.hpp openjdk-lts-11.0.21+9/src/hotspot/share/oops/method.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/method.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/oops/method.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -984,6 +984,15 @@ // Deallocation function for redefine classes or if an error occurs void deallocate_contents(ClassLoaderData* loader_data); + Method* get_new_method() const { + InstanceKlass* holder = method_holder(); + Method* new_method = holder->method_with_idnum(orig_method_idnum()); + + assert(new_method != NULL, "method_with_idnum() should not be null"); + assert(this != new_method, "sanity check"); + return new_method; + } + // Printing #ifndef PRODUCT void print_on(outputStream* st) const; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/oopHandle.hpp openjdk-lts-11.0.21+9/src/hotspot/share/oops/oopHandle.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/oops/oopHandle.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/oops/oopHandle.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -43,6 +43,10 @@ OopHandle() : _obj(NULL) {} OopHandle(oop* w) : _obj(w) {} + void swap(OopHandle& copy) { + ::swap(_obj, copy._obj); + } + inline oop resolve() const; inline oop peek() const; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/library_call.cpp openjdk-lts-11.0.21+9/src/hotspot/share/opto/library_call.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/library_call.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/opto/library_call.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -279,8 +279,13 @@ bool inline_arraycopy(); AllocateArrayNode* tightly_coupled_allocation(Node* ptr, RegionNode* slow_region); + static CallStaticJavaNode* get_uncommon_trap_from_success_proj(Node* node); + SafePointNode* create_safepoint_with_state_before_array_allocation(const AllocateArrayNode* alloc) const; + void replace_unrelated_uncommon_traps_with_alloc_state(AllocateArrayNode* alloc, JVMState* saved_jvms_before_guards); + void replace_unrelated_uncommon_traps_with_alloc_state(JVMState* saved_jvms_before_guards); + void create_new_uncommon_trap(CallStaticJavaNode* uncommon_trap_call); JVMState* arraycopy_restore_alloc_state(AllocateArrayNode* alloc, int& saved_reexecute_sp); - void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, int saved_reexecute_sp, + void arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms_before_guards, int saved_reexecute_sp, uint new_idx); typedef enum { LS_get_add, LS_get_set, LS_cmp_swap, LS_cmp_swap_weak, LS_cmp_exchange } LoadStoreKind; @@ -1428,7 +1433,7 @@ } assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments"); Node* src = argument(0); // byte[] - Node* tgt = argument(1); // tgt is int ch + Node* int_ch = argument(1); Node* from_index = argument(2); Node* max = argument(3); @@ -1440,6 +1445,15 @@ // Range checks generate_string_range_check(src, src_offset, src_count, true); + + // Check for int_ch >= 0 + Node* int_ch_cmp = _gvn.transform(new CmpINode(int_ch, intcon(0))); + Node* int_ch_bol = _gvn.transform(new BoolNode(int_ch_cmp, BoolTest::ge)); + { + BuildCutout unless(this, int_ch_bol, PROB_MAX); + uncommon_trap(Deoptimization::Reason_intrinsic, + Deoptimization::Action_maybe_recompile); + } if (stopped()) { return true; } @@ -1447,7 +1461,7 @@ RegionNode* region = new RegionNode(3); Node* phi = new PhiNode(region, TypeInt::INT); - Node* result = new StrIndexOfCharNode(control(), memory(TypeAryPtr::BYTES), src_start, src_count, tgt, StrIntrinsicNode::none); + Node* result = new StrIndexOfCharNode(control(), memory(TypeAryPtr::BYTES), src_start, src_count, int_ch, StrIntrinsicNode::none); C->set_has_split_ifs(true); // Has chance for split-if optimization _gvn.transform(result); @@ -4534,24 +4548,7 @@ } if (no_interfering_store) { - JVMState* old_jvms = alloc->jvms()->clone_shallow(C); - uint size = alloc->req(); - SafePointNode* sfpt = new SafePointNode(size, old_jvms); - old_jvms->set_map(sfpt); - for (uint i = 0; i < size; i++) { - sfpt->init_req(i, alloc->in(i)); - } - // re-push array length for deoptimization - sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength)); - old_jvms->set_sp(old_jvms->sp()+1); - old_jvms->set_monoff(old_jvms->monoff()+1); - old_jvms->set_scloff(old_jvms->scloff()+1); - old_jvms->set_endoff(old_jvms->endoff()+1); - old_jvms->set_should_reexecute(true); - - sfpt->set_i_o(map()->i_o()); - sfpt->set_memory(map()->memory()); - sfpt->set_control(map()->control()); + SafePointNode* sfpt = create_safepoint_with_state_before_array_allocation(alloc); JVMState* saved_jvms = jvms(); saved_reexecute_sp = _reexecute_sp; @@ -4566,6 +4563,30 @@ return NULL; } +// Clone the JVMState of the array allocation and create a new safepoint with it. Re-push the array length to the stack +// such that uncommon traps can be emitted to re-execute the array allocation in the interpreter. +SafePointNode* LibraryCallKit::create_safepoint_with_state_before_array_allocation(const AllocateArrayNode* alloc) const { + JVMState* old_jvms = alloc->jvms()->clone_shallow(C); + uint size = alloc->req(); + SafePointNode* sfpt = new SafePointNode(size, old_jvms); + old_jvms->set_map(sfpt); + for (uint i = 0; i < size; i++) { + sfpt->init_req(i, alloc->in(i)); + } + // re-push array length for deoptimization + sfpt->ins_req(old_jvms->stkoff() + old_jvms->sp(), alloc->in(AllocateNode::ALength)); + old_jvms->set_sp(old_jvms->sp()+1); + old_jvms->set_monoff(old_jvms->monoff()+1); + old_jvms->set_scloff(old_jvms->scloff()+1); + old_jvms->set_endoff(old_jvms->endoff()+1); + old_jvms->set_should_reexecute(true); + + sfpt->set_i_o(map()->i_o()); + sfpt->set_memory(map()->memory()); + sfpt->set_control(map()->control()); + return sfpt; +} + // In case of a deoptimization, we restart execution at the // allocation, allocating a new array. We would leave an uninitialized // array in the heap that GCs wouldn't expect. Move the allocation @@ -4573,18 +4594,20 @@ // deoptimize. This is possible because tightly_coupled_allocation() // guarantees there's no observer of the allocated array at this point // and the control flow is simple enough. -void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms, +void LibraryCallKit::arraycopy_move_allocation_here(AllocateArrayNode* alloc, Node* dest, JVMState* saved_jvms_before_guards, int saved_reexecute_sp, uint new_idx) { - if (saved_jvms != NULL && !stopped()) { + if (saved_jvms_before_guards != NULL && !stopped()) { + replace_unrelated_uncommon_traps_with_alloc_state(alloc, saved_jvms_before_guards); + assert(alloc != NULL, "only with a tightly coupled allocation"); // restore JVM state to the state at the arraycopy - saved_jvms->map()->set_control(map()->control()); - assert(saved_jvms->map()->memory() == map()->memory(), "memory state changed?"); - assert(saved_jvms->map()->i_o() == map()->i_o(), "IO state changed?"); + saved_jvms_before_guards->map()->set_control(map()->control()); + assert(saved_jvms_before_guards->map()->memory() == map()->memory(), "memory state changed?"); + assert(saved_jvms_before_guards->map()->i_o() == map()->i_o(), "IO state changed?"); // If we've improved the types of some nodes (null check) while // emitting the guards, propagate them to the current state - map()->replaced_nodes().apply(saved_jvms->map(), new_idx); - set_jvms(saved_jvms); + map()->replaced_nodes().apply(saved_jvms_before_guards->map(), new_idx); + set_jvms(saved_jvms_before_guards); _reexecute_sp = saved_reexecute_sp; // Remove the allocation from above the guards @@ -4660,6 +4683,58 @@ } } +// Unrelated UCTs between the array allocation and the array copy, which are considered safe by tightly_coupled_allocation(), +// need to be replaced by an UCT with a state before the array allocation (including the array length). This is necessary +// because we could hit one of these UCTs (which are executed before the emitted array copy guards and the actual array +// allocation which is moved down in arraycopy_move_allocation_here()). When later resuming execution in the interpreter, +// we would have wrongly skipped the array allocation. To prevent this, we resume execution at the array allocation in +// the interpreter similar to what we are doing for the newly emitted guards for the array copy. +void LibraryCallKit::replace_unrelated_uncommon_traps_with_alloc_state(AllocateArrayNode* alloc, + JVMState* saved_jvms_before_guards) { + if (saved_jvms_before_guards->map()->control()->is_IfProj()) { + // There is at least one unrelated uncommon trap which needs to be replaced. + SafePointNode* sfpt = create_safepoint_with_state_before_array_allocation(alloc); + + JVMState* saved_jvms = jvms(); + const int saved_reexecute_sp = _reexecute_sp; + set_jvms(sfpt->jvms()); + _reexecute_sp = jvms()->sp(); + + replace_unrelated_uncommon_traps_with_alloc_state(saved_jvms_before_guards); + + // Restore state + set_jvms(saved_jvms); + _reexecute_sp = saved_reexecute_sp; + } +} + +// Replace the unrelated uncommon traps with new uncommon trap nodes by reusing the action and reason. The new uncommon +// traps will have the state of the array allocation. Let the old uncommon trap nodes die. +void LibraryCallKit::replace_unrelated_uncommon_traps_with_alloc_state(JVMState* saved_jvms_before_guards) { + Node* if_proj = saved_jvms_before_guards->map()->control(); // Start the search right before the newly emitted guards + while (if_proj->is_IfProj()) { + CallStaticJavaNode* uncommon_trap = get_uncommon_trap_from_success_proj(if_proj); + if (uncommon_trap != NULL) { + create_new_uncommon_trap(uncommon_trap); + } + assert(if_proj->in(0)->is_If(), "must be If"); + if_proj = if_proj->in(0)->in(0); + } + assert(if_proj->is_Proj() && if_proj->in(0)->is_Initialize(), + "must have reached control projection of init node"); +} + +void LibraryCallKit::create_new_uncommon_trap(CallStaticJavaNode* uncommon_trap_call) { + const int trap_request = uncommon_trap_call->uncommon_trap_request(); + assert(trap_request != 0, "no valid UCT trap request"); + PreserveJVMState pjvms(this); + set_control(uncommon_trap_call->in(0)); + uncommon_trap(Deoptimization::trap_request_reason(trap_request), + Deoptimization::trap_request_action(trap_request)); + assert(stopped(), "Should be stopped"); + _gvn.hash_delete(uncommon_trap_call); + uncommon_trap_call->set_req(0, top()); // not used anymore, kill it +} //------------------------------inline_arraycopy----------------------- // public static native void java.lang.System.arraycopy(Object src, int srcPos, @@ -4680,12 +4755,12 @@ AllocateArrayNode* alloc = tightly_coupled_allocation(dest, NULL); int saved_reexecute_sp = -1; - JVMState* saved_jvms = arraycopy_restore_alloc_state(alloc, saved_reexecute_sp); + JVMState* saved_jvms_before_guards = arraycopy_restore_alloc_state(alloc, saved_reexecute_sp); // See arraycopy_restore_alloc_state() comment // if alloc == NULL we don't have to worry about a tightly coupled allocation so we can emit all needed guards - // if saved_jvms != NULL (then alloc != NULL) then we can handle guards and a tightly coupled allocation - // if saved_jvms == NULL and alloc != NULL, we can't emit any guards - bool can_emit_guards = (alloc == NULL || saved_jvms != NULL); + // if saved_jvms_before_guards != NULL (then alloc != NULL) then we can handle guards and a tightly coupled allocation + // if saved_jvms_before_guards == NULL and alloc != NULL, we can't emit any guards + bool can_emit_guards = (alloc == NULL || saved_jvms_before_guards != NULL); // The following tests must be performed // (1) src and dest are arrays. @@ -4701,12 +4776,12 @@ // (3) src and dest must not be null. // always do this here because we need the JVM state for uncommon traps Node* null_ctl = top(); - src = saved_jvms != NULL ? null_check_oop(src, &null_ctl, true, true) : null_check(src, T_ARRAY); + src = saved_jvms_before_guards != NULL ? null_check_oop(src, &null_ctl, true, true) : null_check(src, T_ARRAY); assert(null_ctl->is_top(), "no null control here"); dest = null_check(dest, T_ARRAY); if (!can_emit_guards) { - // if saved_jvms == NULL and alloc != NULL, we don't emit any + // if saved_jvms_before_guards == NULL and alloc != NULL, we don't emit any // guards but the arraycopy node could still take advantage of a // tightly allocated allocation. tightly_coupled_allocation() is // called again to make sure it takes the null check above into @@ -4820,7 +4895,7 @@ ciMethod* trap_method = method(); int trap_bci = bci(); - if (saved_jvms != NULL) { + if (saved_jvms_before_guards != NULL) { trap_method = alloc->jvms()->method(); trap_bci = alloc->jvms()->bci(); } @@ -4891,10 +4966,9 @@ const TypeKlassPtr* dest_klass_t = _gvn.type(dest_klass)->is_klassptr(); const Type *toop = TypeOopPtr::make_from_klass(dest_klass_t->klass()); src = _gvn.transform(new CheckCastPPNode(control(), src, toop)); + arraycopy_move_allocation_here(alloc, dest, saved_jvms_before_guards, saved_reexecute_sp, new_idx); } - arraycopy_move_allocation_here(alloc, dest, saved_jvms, saved_reexecute_sp, new_idx); - if (stopped()) { return true; } @@ -4960,32 +5034,27 @@ // There may be guards which feed into the slow_region. // Any other control flow means that we might not get a chance // to finish initializing the allocated object. - if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) { - IfNode* iff = ctl->in(0)->as_If(); - Node* not_ctl = iff->proj_out_or_null(1 - ctl->as_Proj()->_con); - assert(not_ctl != NULL && not_ctl != ctl, "found alternate"); - if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) { - ctl = iff->in(0); // This test feeds the known slow_region. - continue; - } - // One more try: Various low-level checks bottom out in - // uncommon traps. If the debug-info of the trap omits - // any reference to the allocation, as we've already - // observed, then there can be no objection to the trap. - bool found_trap = false; - for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) { - Node* obs = not_ctl->fast_out(j); - if (obs->in(0) == not_ctl && obs->is_Call() && - (obs->as_Call()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) { - found_trap = true; break; + // This code is removed by "8263615: Cleanup tightly_coupled_allocation" + // I had to adapt it when backporting "8297730: C2: Arraycopy intrinsic throws incorrect exception" + if (slow_region != NULL) { + if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) { + IfNode* iff = ctl->in(0)->as_If(); + Node* not_ctl = iff->proj_out_or_null(1 - ctl->as_Proj()->_con); + if (slow_region->find_edge(not_ctl) >= 1) { + ctl = iff->in(0); // This test feeds the known slow_region. + continue; } } - if (found_trap) { - ctl = iff->in(0); // This test feeds a harmless uncommon trap. - continue; - } } - return NULL; + // Various low-level checks bottom out in uncommon traps. These + // are considered safe since we've already checked above that + // there is no unexpected observer of this allocation. + if (get_uncommon_trap_from_success_proj(ctl) != NULL) { + assert(ctl->in(0)->is_If(), "must be If"); + ctl = ctl->in(0)->in(0); + } else { + return NULL; + } } // If we get this far, we have an allocation which immediately @@ -4996,6 +5065,20 @@ return alloc; } +CallStaticJavaNode* LibraryCallKit::get_uncommon_trap_from_success_proj(Node* node) { + if (node->is_IfProj()) { + Node* other_proj = node->as_IfProj()->other_if_proj(); + for (DUIterator_Fast jmax, j = other_proj->fast_outs(jmax); j < jmax; j++) { + Node* obs = other_proj->fast_out(j); + if (obs->in(0) == other_proj && obs->is_CallStaticJava() && + (obs->as_CallStaticJava()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point())) { + return obs->as_CallStaticJava(); + } + } + } + return NULL; +} + //-------------inline_encodeISOArray----------------------------------- // encode char[] to byte[] in ISO_8859_1 bool LibraryCallKit::inline_encodeISOArray() { diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/loopopts.cpp openjdk-lts-11.0.21+9/src/hotspot/share/opto/loopopts.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/loopopts.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/opto/loopopts.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -504,7 +504,7 @@ n23_loop == n_loop ) { Node *add1 = new AddPNode( n->in(1), n->in(2)->in(2), n->in(3) ); // Stuff new AddP in the loop preheader - register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) ); + register_new_node( add1, n_loop->_head->as_Loop()->skip_strip_mined(1)->in(LoopNode::EntryControl) ); Node *add2 = new AddPNode( n->in(1), add1, n->in(2)->in(3) ); register_new_node( add2, n_ctrl ); _igvn.replace_node( n, add2 ); @@ -525,7 +525,7 @@ if (!is_member(n_loop,get_ctrl(I))) { Node *add1 = new AddPNode(n->in(1), n->in(2), I); // Stuff new AddP in the loop preheader - register_new_node(add1, n_loop->_head->in(LoopNode::EntryControl)); + register_new_node(add1, n_loop->_head->as_Loop()->skip_strip_mined(1)->in(LoopNode::EntryControl)); Node *add2 = new AddPNode(n->in(1), add1, V); register_new_node(add2, n_ctrl); _igvn.replace_node(n, add2); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/loopTransform.cpp openjdk-lts-11.0.21+9/src/hotspot/share/opto/loopTransform.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/loopTransform.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/opto/loopTransform.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -3240,7 +3240,12 @@ // counted loop has limit check predicate. Node* phi = cl->phi(); Node* exact_limit = phase->exact_limit(this); - Node* final_iv = new SubINode(exact_limit, cl->stride()); + + // We need to pin the exact limit to prevent it from floating above the zero trip guard. + Node * cast_ii = ConstraintCastNode::make_cast(Op_CastII, cl->in(LoopNode::EntryControl), exact_limit, phase->_igvn.type(exact_limit), true); + phase->register_new_node(cast_ii, cl->in(LoopNode::EntryControl)); + + Node* final_iv = new SubINode(cast_ii, cl->stride()); phase->register_new_node(final_iv, cl->in(LoopNode::EntryControl)); phase->_igvn.replace_node(phi, final_iv); diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/parse1.cpp openjdk-lts-11.0.21+9/src/hotspot/share/opto/parse1.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/parse1.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/opto/parse1.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -610,8 +610,6 @@ // Parse all the basic blocks. do_all_blocks(); - C->set_default_node_notes(caller_nn); - // Check for bailouts during conversion to graph if (failing()) { if (log) log->done("parse"); @@ -622,6 +620,10 @@ set_map(entry_map); do_exits(); + // Only reset this now, to make sure that debug information emitted + // for exiting control flow still refers to the inlined method. + C->set_default_node_notes(caller_nn); + if (log) log->done("parse nodes='%d' live='%d' memory='" SIZE_FORMAT "'", C->unique(), C->live_nodes(), C->node_arena()->used()); } diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/phaseX.cpp openjdk-lts-11.0.21+9/src/hotspot/share/opto/phaseX.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/opto/phaseX.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/opto/phaseX.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -482,6 +482,14 @@ uint worklist_size = worklist->size(); + GrowableArray* old_node_note_array = C->node_note_array(); + if (old_node_note_array != NULL) { + int new_size = (_useful.size() >> 8) + 1; // The node note array uses blocks, see C->_log2_node_notes_block_size + new_size = MAX2(8, new_size); + C->set_node_note_array(new (C->comp_arena()) GrowableArray (C->comp_arena(), new_size, 0, NULL)); + C->grow_node_notes(C->node_note_array(), new_size); + } + // Iterate over the set of live nodes. for (uint current_idx = 0; current_idx < _useful.size(); current_idx++) { Node* n = _useful.at(current_idx); @@ -497,6 +505,11 @@ assert(_old2new_map.at(n->_idx) == -1, "already seen"); _old2new_map.at_put(n->_idx, current_idx); + if (old_node_note_array != NULL) { + Node_Notes* nn = C->locate_node_notes(old_node_note_array, n->_idx); + C->set_node_notes_at(current_idx, nn); + } + n->set_idx(current_idx); // Update node ID. if (in_worklist) { diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/prims/jvmtiThreadState.hpp openjdk-lts-11.0.21+9/src/hotspot/share/prims/jvmtiThreadState.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/prims/jvmtiThreadState.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/prims/jvmtiThreadState.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -411,14 +411,14 @@ JvmtiThreadState *state) : _state(state), _scratch_class(scratch_class) { _state->set_class_versions_map(the_class, scratch_class); - _scratch_mirror = _scratch_class->java_mirror_handle(); - _scratch_class->set_java_mirror_handle(the_class->java_mirror_handle()); + _scratch_mirror = the_class->java_mirror_handle(); // this is a copy that is swapped + _scratch_class->swap_java_mirror_handle(_scratch_mirror); } ~RedefineVerifyMark() { // Restore the scratch class's mirror, so when scratch_class is removed // the correct mirror pointing to it can be cleared. - _scratch_class->set_java_mirror_handle(_scratch_mirror); + _scratch_class->swap_java_mirror_handle(_scratch_mirror); _state->clear_class_versions_map(); } }; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/prims/whitebox.cpp openjdk-lts-11.0.21+9/src/hotspot/share/prims/whitebox.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/prims/whitebox.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/prims/whitebox.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * 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,6 +94,7 @@ #endif // INCLUDE_AOT #ifdef LINUX +#include "os_linux.hpp" #include "osContainer_linux.hpp" #include "cgroupSubsystem_linux.hpp" #endif @@ -1832,7 +1833,7 @@ return MetaspaceShared::open_archive_heap_region_mapped(); WB_END -WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env)) +WB_ENTRY(jboolean, WB_IsCDSIncluded(JNIEnv* env)) #if INCLUDE_CDS # ifdef _LP64 if (!UseCompressedOops || !UseCompressedClassPointers) { @@ -1851,7 +1852,7 @@ WB_END -WB_ENTRY(jboolean, WB_IsJFRIncludedInVmBuild(JNIEnv* env)) +WB_ENTRY(jboolean, WB_IsJFRIncluded(JNIEnv* env)) #if INCLUDE_JFR return true; #else @@ -2026,6 +2027,18 @@ return false; WB_END +// Physical memory of the host machine (including containers) +WB_ENTRY(jlong, WB_HostPhysicalMemory(JNIEnv* env, jobject o)) + LINUX_ONLY(return os::Linux::physical_memory();) + return os::physical_memory(); +WB_END + +// Physical swap of the host machine (including containers), Linux only. +WB_ENTRY(jlong, WB_HostPhysicalSwap(JNIEnv* env, jobject o)) + LINUX_ONLY(return (jlong)os::Linux::host_swap();) + return -1; // Not used/implemented on other platforms +WB_END + WB_ENTRY(jint, WB_ValidateCgroup(JNIEnv* env, jobject o, jstring proc_cgroups, @@ -2282,8 +2295,8 @@ {CC"areSharedStringsIgnored", CC"()Z", (void*)&WB_AreSharedStringsIgnored }, {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences}, {CC"areOpenArchiveHeapObjectsMapped", CC"()Z", (void*)&WB_AreOpenArchiveHeapObjectsMapped}, - {CC"isCDSIncludedInVmBuild", CC"()Z", (void*)&WB_IsCDSIncludedInVmBuild }, - {CC"isJFRIncludedInVmBuild", CC"()Z", (void*)&WB_IsJFRIncludedInVmBuild }, + {CC"isCDSIncluded", CC"()Z", (void*)&WB_IsCDSIncluded }, + {CC"isJFRIncluded", CC"()Z", (void*)&WB_IsJFRIncluded }, {CC"isJavaHeapArchiveSupported", CC"()Z", (void*)&WB_IsJavaHeapArchiveSupported }, {CC"clearInlineCaches0", CC"(Z)V", (void*)&WB_ClearInlineCaches }, @@ -2305,6 +2318,8 @@ {CC"validateCgroup", CC"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void*)&WB_ValidateCgroup }, + {CC"hostPhysicalMemory", CC"()J", (void*)&WB_HostPhysicalMemory }, + {CC"hostPhysicalSwap", CC"()J", (void*)&WB_HostPhysicalSwap }, {CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo }, {CC"disableElfSectionCache", CC"()V", (void*)&WB_DisableElfSectionCache }, {CC"aotLibrariesCount", CC"()I", (void*)&WB_AotLibrariesCount }, diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/runtime/frame.cpp openjdk-lts-11.0.21+9/src/hotspot/share/runtime/frame.cpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/runtime/frame.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/runtime/frame.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -44,6 +44,7 @@ #include "runtime/monitorChunk.hpp" #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/signature.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" @@ -240,6 +241,14 @@ return (jfa->last_Java_sp() > sp()); } +Method* frame::safe_interpreter_frame_method() const { + Method** m_addr = interpreter_frame_method_addr(); + if (m_addr == NULL) { + return NULL; + } + return (Method*) SafeFetchN((intptr_t*) m_addr, 0); +} + bool frame::should_be_deoptimized() const { if (_deopt_state == is_deoptimized || !is_compiled_frame() ) return false; diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/runtime/frame.hpp openjdk-lts-11.0.21+9/src/hotspot/share/runtime/frame.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/runtime/frame.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/runtime/frame.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -168,6 +168,8 @@ bool is_entry_frame_valid(JavaThread* thread) const; + Method* safe_interpreter_frame_method() const; + // All frames: // A low-level interface for vframes: diff -Nru openjdk-lts-11.0.20.1+1/src/hotspot/share/runtime/globals.hpp openjdk-lts-11.0.21+9/src/hotspot/share/runtime/globals.hpp --- openjdk-lts-11.0.20.1+1/src/hotspot/share/runtime/globals.hpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/hotspot/share/runtime/globals.hpp 2023-10-06 05:33:33.000000000 +0000 @@ -133,8 +133,8 @@ // notproduct flags are settable / visible only during development and are not declared in the PRODUCT version // A flag must be declared with one of the following types: -// bool, int, uint, intx, uintx, size_t, ccstr, double, or uint64_t. -// The type "ccstr" is an alias for "const char*" and is used +// bool, int, uint, intx, uintx, size_t, ccstr, ccstrlist, double, or uint64_t. +// The type "ccstr" and "ccstrlist" are an alias for "const char*" and is used // only in this file, because the macrology requires single-token type names. // Note: Diagnostic options not meant for VM tuning or for product modes. diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/macosx/classes/apple/security/KeychainStore.java openjdk-lts-11.0.21+9/src/java.base/macosx/classes/apple/security/KeychainStore.java --- openjdk-lts-11.0.20.1+1/src/java.base/macosx/classes/apple/security/KeychainStore.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/macosx/classes/apple/security/KeychainStore.java 2023-10-06 05:33:33.000000000 +0000 @@ -108,12 +108,13 @@ private Hashtable entries = new Hashtable<>(); /** - * Algorithm identifiers and corresponding OIDs for the contents of the PKCS12 bag we get from the Keychain. + * Algorithm identifiers and corresponding OIDs for the contents of the + * PKCS12 bag we get from the Keychain. */ - private static final int keyBag[] = {1, 2, 840, 113549, 1, 12, 10, 1, 2}; - private static final int pbeWithSHAAnd3KeyTripleDESCBC[] = {1, 2, 840, 113549, 1, 12, 1, 3}; - private static ObjectIdentifier PKCS8ShroudedKeyBag_OID; - private static ObjectIdentifier pbeWithSHAAnd3KeyTripleDESCBC_OID; + private static ObjectIdentifier PKCS8ShroudedKeyBag_OID = + ObjectIdentifier.of(KnownOIDs.PKCS8ShroudedKeyBag); + private static ObjectIdentifier pbeWithSHAAnd3KeyTripleDESCBC_OID = + ObjectIdentifier.of(KnownOIDs.PBEWithSHA1AndDESede); /** * Constnats used in PBE decryption. @@ -131,12 +132,6 @@ return null; } }); - try { - PKCS8ShroudedKeyBag_OID = new ObjectIdentifier(keyBag); - pbeWithSHAAnd3KeyTripleDESCBC_OID = new ObjectIdentifier(pbeWithSHAAnd3KeyTripleDESCBC); - } catch (IOException ioe) { - // should not happen - } } private static void permissionCheck() { diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c openjdk-lts-11.0.21+9/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c --- openjdk-lts-11.0.20.1+1/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/macosx/native/libjava/ProcessHandleImpl_macosx.c 2023-10-06 05:33:33.000000000 +0000 @@ -272,7 +272,8 @@ mib[2] = pid; size = (size_t) maxargs; if (sysctl(mib, 3, args, &size, NULL, 0) == -1) { - if (errno != EINVAL) { + if (errno != EINVAL && errno != EIO) { + // If the pid is invalid, the information returned is empty and no exception JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException", "sysctl failed"); } @@ -300,4 +301,3 @@ // Free the arg buffer free(args); } - diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DESedeKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, 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 @@ -25,6 +25,8 @@ package com.sun.crypto.provider; +import java.io.IOException; +import java.io.InvalidObjectException; import java.lang.ref.Reference; import java.security.MessageDigest; import java.security.KeyRep; @@ -43,7 +45,7 @@ final class DESedeKey implements SecretKey { - static final long serialVersionUID = 2463986565756745178L; + private static final long serialVersionUID = 2463986565756745178L; private byte[] key; @@ -111,7 +113,7 @@ for (int i = 1; i < this.key.length; i++) { retval += this.key[i] * i; } - return(retval ^= "desede".hashCode()); + return(retval ^ "desede".hashCode()); } public boolean equals(Object obj) { @@ -133,14 +135,29 @@ } /** - * readObject is called to restore the state of this key from - * a stream. + * Restores the state of this object from the stream. + * + * @param s the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded */ private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException + throws IOException, ClassNotFoundException { s.defaultReadObject(); + if ((key == null) || (key.length != DESedeKeySpec.DES_EDE_KEY_LEN)) { + throw new InvalidObjectException("Wrong key size"); + } key = key.clone(); + + DESKeyGenerator.setParityBit(key, 0); + DESKeyGenerator.setParityBit(key, 8); + DESKeyGenerator.setParityBit(key, 16); + + // Use the cleaner to zero the key when no longer referenced + final byte[] k = key; + CleanerFactory.cleaner().register(this, + () -> java.util.Arrays.fill(k, (byte)0x00)); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DESKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, 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 @@ -25,6 +25,8 @@ package com.sun.crypto.provider; +import java.io.IOException; +import java.io.InvalidObjectException; import java.lang.ref.Reference; import java.security.MessageDigest; import java.security.KeyRep; @@ -43,7 +45,7 @@ final class DESKey implements SecretKey { - static final long serialVersionUID = 7724971015953279128L; + private static final long serialVersionUID = 7724971015953279128L; private byte[] key; @@ -112,7 +114,7 @@ for (int i = 1; i < this.key.length; i++) { retval += this.key[i] * i; } - return(retval ^= "des".hashCode()); + return(retval ^ "des".hashCode()); } public boolean equals(Object obj) { @@ -133,14 +135,27 @@ } /** - * readObject is called to restore the state of this key from - * a stream. + * Restores the state of this object from the stream. + * + * @param s the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded */ private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException + throws IOException, ClassNotFoundException { s.defaultReadObject(); + if ((key == null) || (key.length != DESKeySpec.DES_KEY_LEN)) { + throw new InvalidObjectException("Wrong key size"); + } key = key.clone(); + + DESKeyGenerator.setParityBit(key, 0); + + // Use the cleaner to zero the key when no longer referenced + final byte[] k = key; + CleanerFactory.cleaner().register(this, + () -> java.util.Arrays.fill(k, (byte)0x00)); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DHPrivateKey.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DHPrivateKey.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DHPrivateKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DHPrivateKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, 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 @@ -40,15 +40,13 @@ * algorithm. * * @author Jan Luehe - * - * * @see DHPublicKey * @see java.security.KeyAgreement */ final class DHPrivateKey implements PrivateKey, javax.crypto.interfaces.DHPrivateKey, Serializable { - static final long serialVersionUID = 7565477590005668886L; + private static final long serialVersionUID = 7565477590005668886L; // only supported version of PKCS#8 PrivateKeyInfo private static final BigInteger PKCS8_VERSION = BigInteger.ZERO; @@ -63,16 +61,14 @@ private byte[] encodedKey; // the prime modulus - private BigInteger p; + private final BigInteger p; // the base generator - private BigInteger g; + private final BigInteger g; // the private-value length (optional) private int l; - private int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 }; - /** * Make a DH private key out of a private value x, a prime * modulus p, and a base generator g. @@ -219,7 +215,7 @@ DerOutputStream algid = new DerOutputStream(); // store OID - algid.putOID(new ObjectIdentifier(DH_data)); + algid.putOID(DHPublicKey.DH_OID); // encode parameters DerOutputStream params = new DerOutputStream(); params.putInteger(this.p); @@ -319,4 +315,27 @@ getFormat(), getEncoded()); } + + /** + * Restores the state of this object from the stream. + *

+ * JDK 1.5+ objects use KeyReps instead. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if ((key == null) || (key.length == 0)) { + throw new InvalidObjectException("key not deserializable"); + } + this.key = key.clone(); + if ((encodedKey == null) || (encodedKey.length == 0)) { + throw new InvalidObjectException( + "encoded key not deserializable"); + } + this.encodedKey = encodedKey.clone(); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/DHPublicKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, 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 @@ -40,15 +40,13 @@ * A public key in X.509 format for the Diffie-Hellman key agreement algorithm. * * @author Jan Luehe - * - * * @see DHPrivateKey * @see javax.crypto.KeyAgreement */ final class DHPublicKey implements PublicKey, javax.crypto.interfaces.DHPublicKey, Serializable { - static final long serialVersionUID = 7647557958927458271L; + private static final long serialVersionUID = 7647557958927458271L; // the public key private BigInteger y; @@ -60,15 +58,17 @@ private byte[] encodedKey; // the prime modulus - private BigInteger p; + private final BigInteger p; // the base generator - private BigInteger g; + private final BigInteger g; // the private-value length (optional) private int l; - private int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 }; + // Note: this OID is used by DHPrivateKey as well. + static ObjectIdentifier DH_OID = + ObjectIdentifier.of(KnownOIDs.DiffieHellman); /** * Make a DH public key out of a public value y, a prime @@ -202,7 +202,7 @@ DerOutputStream algid = new DerOutputStream(); // store oid in algid - algid.putOID(new ObjectIdentifier(DH_data)); + algid.putOID(DH_OID); // encode parameters DerOutputStream params = new DerOutputStream(); @@ -320,4 +320,27 @@ getFormat(), getEncoded()); } + + /** + * Restores the state of this object from the stream. + *

+ * JDK 1.5+ objects use KeyReps instead. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if ((key == null) || (key.length == 0)) { + throw new InvalidObjectException("key not deserializable"); + } + this.key = key.clone(); + if ((encodedKey == null) || (encodedKey.length == 0)) { + throw new InvalidObjectException( + "encoded key not deserializable"); + } + this.encodedKey = encodedKey.clone(); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java 2023-10-06 05:33:33.000000000 +0000 @@ -48,6 +48,7 @@ import sun.security.x509.AlgorithmId; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.util.SecurityProperties; /** @@ -67,14 +68,6 @@ final class KeyProtector { - // defined by SunSoft (SKI project) - private static final String PBE_WITH_MD5_AND_DES3_CBC_OID - = "1.3.6.1.4.1.42.2.19.1"; - - // JavaSoft proprietary key-protection algorithm (used to protect private - // keys in the keystore implementation that comes with JDK 1.2) - private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1"; - private static final int MAX_ITERATION_COUNT = 5000000; private static final int MIN_ITERATION_COUNT = 10000; private static final int DEFAULT_ITERATION_COUNT = 200000; @@ -154,7 +147,8 @@ pbeParams.init(pbeSpec); AlgorithmId encrAlg = new AlgorithmId - (new ObjectIdentifier(PBE_WITH_MD5_AND_DES3_CBC_OID), pbeParams); + (ObjectIdentifier.of(KnownOIDs.JAVASOFT_JCEKeyProtector), + pbeParams); return new EncryptedPrivateKeyInfo(encrAlg,encrKey).getEncoded(); } @@ -169,13 +163,13 @@ SecretKey sKey = null; try { String encrAlg = encrInfo.getAlgorithm().getOID().toString(); - if (!encrAlg.equals(PBE_WITH_MD5_AND_DES3_CBC_OID) - && !encrAlg.equals(KEY_PROTECTOR_OID)) { + if (!encrAlg.equals(KnownOIDs.JAVASOFT_JCEKeyProtector.value()) + && !encrAlg.equals(KnownOIDs.JAVASOFT_JDKKeyProtector.value())) { throw new UnrecoverableKeyException("Unsupported encryption " + "algorithm"); } - if (encrAlg.equals(KEY_PROTECTOR_OID)) { + if (encrAlg.equals(KnownOIDs.JAVASOFT_JDKKeyProtector.value())) { // JDK 1.2 style recovery plain = recover(encrInfo.getEncryptedData()); } else { diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java 2023-10-06 05:33:33.000000000 +0000 @@ -55,24 +55,10 @@ private String mdName; private MGF1ParameterSpec mgfSpec; private byte[] p; - private static ObjectIdentifier OID_MGF1; - private static ObjectIdentifier OID_PSpecified; - - static { - try { - OID_MGF1 = new ObjectIdentifier(new int[] {1,2,840,113549,1,1,8}); - } catch (IOException ioe) { - // should not happen - OID_MGF1 = null; - } - try { - OID_PSpecified = - new ObjectIdentifier(new int[] {1,2,840,113549,1,1,9}); - } catch (IOException ioe) { - // should not happen - OID_PSpecified = null; - } - } + private static ObjectIdentifier OID_MGF1 = + ObjectIdentifier.of(KnownOIDs.MGF1); + private static ObjectIdentifier OID_PSpecified = + ObjectIdentifier.of(KnownOIDs.PSpecified); public OAEPParameters() { } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/PBEKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, 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 @@ -25,6 +25,8 @@ package com.sun.crypto.provider; +import java.io.IOException; +import java.io.InvalidObjectException; import java.lang.ref.Reference; import java.security.MessageDigest; import java.security.KeyRep; @@ -44,11 +46,11 @@ */ final class PBEKey implements SecretKey { - static final long serialVersionUID = -2234768909660948176L; + private static final long serialVersionUID = -2234768909660948176L; private byte[] key; - private String type; + private final String type; /** * Creates a PBE key from a given PBE key specification. @@ -109,7 +111,7 @@ for (int i = 1; i < this.key.length; i++) { retval += this.key[i] * i; } - return(retval ^= getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode()); + return(retval ^ getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode()); } public boolean equals(Object obj) { @@ -143,14 +145,37 @@ } /** - * readObject is called to restore the state of this key from - * a stream. + * Restores the state of this object from the stream. + * + * @param s the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded */ private void readObject(java.io.ObjectInputStream s) - throws java.io.IOException, ClassNotFoundException + throws IOException, ClassNotFoundException { s.defaultReadObject(); + if (key == null) { + throw new InvalidObjectException( + "PBEKey couldn't be deserialized"); + } key = key.clone(); + + // Accept "\0" to signify "zero-length password with no terminator". + if (!(key.length == 1 && key[0] == 0)) { + for (int i = 0; i < key.length; i++) { + if ((key[i] < '\u0020') || (key[i] > '\u007E')) { + throw new InvalidObjectException( + "PBEKey had non-ASCII chars"); + } + } + } + + // Use the cleaner to zero the key when no longer referenced + final byte[] k = this.key; + CleanerFactory.cleaner().register(this, + () -> Arrays.fill(k, (byte) 0x00)); + } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -90,57 +90,18 @@ * * */ - abstract class PBES2Parameters extends AlgorithmParametersSpi { - private static final int pkcs5PBKDF2[] = - {1, 2, 840, 113549, 1, 5, 12}; - private static final int pkcs5PBES2[] = - {1, 2, 840, 113549, 1, 5, 13}; - private static final int hmacWithSHA1[] = - {1, 2, 840, 113549, 2, 7}; - private static final int hmacWithSHA224[] = - {1, 2, 840, 113549, 2, 8}; - private static final int hmacWithSHA256[] = - {1, 2, 840, 113549, 2, 9}; - private static final int hmacWithSHA384[] = - {1, 2, 840, 113549, 2, 10}; - private static final int hmacWithSHA512[] = - {1, 2, 840, 113549, 2, 11}; - private static final int aes128CBC[] = - {2, 16, 840, 1, 101, 3, 4, 1, 2}; - private static final int aes192CBC[] = - {2, 16, 840, 1, 101, 3, 4, 1, 22}; - private static final int aes256CBC[] = - {2, 16, 840, 1, 101, 3, 4, 1, 42}; - - private static ObjectIdentifier pkcs5PBKDF2_OID; - private static ObjectIdentifier pkcs5PBES2_OID; - private static ObjectIdentifier hmacWithSHA1_OID; - private static ObjectIdentifier hmacWithSHA224_OID; - private static ObjectIdentifier hmacWithSHA256_OID; - private static ObjectIdentifier hmacWithSHA384_OID; - private static ObjectIdentifier hmacWithSHA512_OID; - private static ObjectIdentifier aes128CBC_OID; - private static ObjectIdentifier aes192CBC_OID; - private static ObjectIdentifier aes256CBC_OID; - - static { - try { - pkcs5PBKDF2_OID = new ObjectIdentifier(pkcs5PBKDF2); - pkcs5PBES2_OID = new ObjectIdentifier(pkcs5PBES2); - hmacWithSHA1_OID = new ObjectIdentifier(hmacWithSHA1); - hmacWithSHA224_OID = new ObjectIdentifier(hmacWithSHA224); - hmacWithSHA256_OID = new ObjectIdentifier(hmacWithSHA256); - hmacWithSHA384_OID = new ObjectIdentifier(hmacWithSHA384); - hmacWithSHA512_OID = new ObjectIdentifier(hmacWithSHA512); - aes128CBC_OID = new ObjectIdentifier(aes128CBC); - aes192CBC_OID = new ObjectIdentifier(aes192CBC); - aes256CBC_OID = new ObjectIdentifier(aes256CBC); - } catch (IOException ioe) { - // should not happen - } - } + private static ObjectIdentifier pkcs5PBKDF2_OID = + ObjectIdentifier.of(KnownOIDs.PBKDF2WithHmacSHA1); + private static ObjectIdentifier pkcs5PBES2_OID = + ObjectIdentifier.of(KnownOIDs.PBES2); + private static ObjectIdentifier aes128CBC_OID = + ObjectIdentifier.of(KnownOIDs.AES_128$CBC$NoPadding); + private static ObjectIdentifier aes192CBC_OID = + ObjectIdentifier.of(KnownOIDs.AES_192$CBC$NoPadding); + private static ObjectIdentifier aes256CBC_OID = + ObjectIdentifier.of(KnownOIDs.AES_256$CBC$NoPadding); // the PBES2 algorithm name private String pbes2AlgorithmName = null; @@ -155,7 +116,8 @@ private AlgorithmParameterSpec cipherParam = null; // the key derivation function (default is HmacSHA1) - private ObjectIdentifier kdfAlgo_OID = hmacWithSHA1_OID; + private ObjectIdentifier kdfAlgo_OID = + ObjectIdentifier.of(KnownOIDs.HmacSHA1); // the encryption function private ObjectIdentifier cipherAlgo_OID = null; @@ -200,19 +162,11 @@ switch (kdfAlgo) { case "HmacSHA1": - kdfAlgo_OID = hmacWithSHA1_OID; - break; case "HmacSHA224": - kdfAlgo_OID = hmacWithSHA224_OID; - break; case "HmacSHA256": - kdfAlgo_OID = hmacWithSHA256_OID; - break; case "HmacSHA384": - kdfAlgo_OID = hmacWithSHA384_OID; - break; case "HmacSHA512": - kdfAlgo_OID = hmacWithSHA512_OID; + kdfAlgo_OID = ObjectIdentifier.of(KnownOIDs.findMatch(kdfAlgo)); break; default: throw new NoSuchAlgorithmException( @@ -284,7 +238,7 @@ } cipherAlgo = parseES(pBES2_params.data.getDerValue()); - pbes2AlgorithmName = new StringBuilder().append("PBEWith") + this.pbes2AlgorithmName = new StringBuilder().append("PBEWith") .append(kdfAlgo).append("And").append(cipherAlgo).toString(); } @@ -335,21 +289,18 @@ } if (prf != null) { kdfAlgo_OID = prf.data.getOID(); - if (hmacWithSHA1_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA1"; - } else if (hmacWithSHA224_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA224"; - } else if (hmacWithSHA256_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA256"; - } else if (hmacWithSHA384_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA384"; - } else if (hmacWithSHA512_OID.equals(kdfAlgo_OID)) { - kdfAlgo = "HmacSHA512"; - } else { + KnownOIDs o = KnownOIDs.findMatch(kdfAlgo_OID.toString()); + if (o == null || (!o.stdName().equals("HmacSHA1") && + !o.stdName().equals("HmacSHA224") && + !o.stdName().equals("HmacSHA256") && + !o.stdName().equals("HmacSHA384") && + !o.stdName().equals("HmacSHA512"))) { throw new IOException("PBE parameter parsing error: " + "expecting the object identifier for a HmacSHA key " + "derivation function"); } + kdfAlgo = o.stdName(); + if (prf.data.available() != 0) { // parameter is 'NULL' for all HmacSHA KDFs DerValue parameter = prf.data.getDerValue(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,7 +25,7 @@ package com.sun.crypto.provider; -import java.io.ObjectStreamException; +import java.io.*; import java.lang.ref.Reference; import java.nio.ByteBuffer; import java.nio.CharBuffer; @@ -55,14 +55,14 @@ */ final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey { - static final long serialVersionUID = -2234868909660948157L; + private static final long serialVersionUID = -2234868909660948157L; - private char[] passwd; - private byte[] salt; - private int iterCount; + private final char[] passwd; + private final byte[] salt; + private final int iterCount; private byte[] key; - private Mac prf; + private final Mac prf; private static byte[] getPasswordBytes(char[] passwd) { Charset utf8 = Charset.forName("UTF-8"); @@ -144,12 +144,13 @@ int intR = keyLength - (intL - 1)*hlen; // residue byte[] ui = new byte[hlen]; byte[] ti = new byte[hlen]; + String algName = prf.getAlgorithm(); // SecretKeySpec cannot be used, since password can be empty here. SecretKey macKey = new SecretKey() { private static final long serialVersionUID = 7874493593505141603L; @Override public String getAlgorithm() { - return prf.getAlgorithm(); + return algName; } @Override public String getFormat() { @@ -162,18 +163,26 @@ @Override public int hashCode() { return Arrays.hashCode(password) * 41 + - prf.getAlgorithm().toLowerCase(Locale.ENGLISH).hashCode(); + algName.toLowerCase(Locale.ENGLISH).hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (this.getClass() != obj.getClass()) return false; SecretKey sk = (SecretKey)obj; - return prf.getAlgorithm().equalsIgnoreCase( + return algName.equalsIgnoreCase( sk.getAlgorithm()) && MessageDigest.isEqual(password, sk.getEncoded()); } + // This derived key can't be deserialized. + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "PBKDF2KeyImpl SecretKeys are not " + + "directly deserializable"); + } }; + prf.init(macKey); byte[] ibytes = new byte[4]; @@ -282,4 +291,19 @@ return new KeyRep(KeyRep.Type.SECRET, getAlgorithm(), getFormat(), getEncoded()); } + + /** + * Restores the state of this object from the stream. + *

+ * Deserialization of this class is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "PBKDF2KeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java 2023-10-06 05:33:33.000000000 +0000 @@ -32,8 +32,7 @@ import java.util.HashMap; import java.util.List; import static sun.security.util.SecurityConstants.PROVIDER_VER; -import static sun.security.provider.SunEntries.createAliases; -import static sun.security.provider.SunEntries.createAliasesWithOid; +import static sun.security.util.SecurityProviderConstants.*; /** * The "SunJCE" Cryptographic Service Provider. @@ -99,9 +98,22 @@ } static SecureRandom getRandom() { return SecureRandomHolder.RANDOM; } - private void ps(String type, String algo, String cn, - List aliases, HashMap attrs) { - putService(new Provider.Service(this, type, algo, cn, aliases, attrs)); + // ps: putService + private void ps(String type, String algo, String cn) { + putService(new Provider.Service(this, type, algo, cn, null, null)); + } + + private void ps(String type, String algo, String cn, List als, + HashMap attrs) { + putService(new Provider.Service(this, type, algo, cn, als, + attrs)); + } + + // psA: putService with default aliases + private void psA(String type, String algo, String cn, + HashMap attrs) { + putService(new Provider.Service(this, type, algo, cn, getAliases(algo), + attrs)); } public SunJCE() { @@ -127,57 +139,6 @@ } void putEntries() { - // common aliases and oids - List aesAliases = createAliases("Rijndael"); - List desEdeAliases = createAliases("TripleDES"); - List arcFourAliases = createAliases("RC4"); - List sunTlsMSAliases = createAliases( - "SunTls12MasterSecret", "SunTlsExtendedMasterSecret" - ); - List sunTlsKMAliases = createAliases("SunTls12KeyMaterial"); - List sunTlsRsaPMSAliases = createAliases("SunTls12RsaPremasterSecret"); - - String aes128Oid = "2.16.840.1.101.3.4.1."; - String aes192Oid = "2.16.840.1.101.3.4.1.2"; - String aes256Oid = "2.16.840.1.101.3.4.1.4"; - - List pkcs12RC4_128Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.1"); - - List pkcs12RC4_40Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.2"); - - List pkcs12DESedeAliases = - createAliasesWithOid("1.2.840.113549.1.12.1.3"); - - List pkcs12RC2_128Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.5"); - - List pkcs12RC2_40Aliases = - createAliasesWithOid("1.2.840.113549.1.12.1.6"); - - List pkcs5MD5_DESAliases = - createAliasesWithOid("1.2.840.113549.1.5.3", "PBE"); - - List pkcs5PBKDF2Aliases = - createAliasesWithOid("1.2.840.113549.1.5.12"); - - List pkcs5PBES2Aliases = - createAliasesWithOid("1.2.840.113549.1.5.13"); - - List diffieHellmanAliases = - createAliasesWithOid("1.2.840.113549.1.3.1", "DH"); - - List chachaPolyAliases = - createAliasesWithOid("1.2.840.113549.1.9.16.3.18"); - - String macOidBase = "1.2.840.113549.2."; - List macSHA1Aliases = createAliasesWithOid(macOidBase + "7"); - List macSHA224Aliases = createAliasesWithOid(macOidBase + "8"); - List macSHA256Aliases = createAliasesWithOid(macOidBase + "9"); - List macSHA384Aliases = createAliasesWithOid(macOidBase + "10"); - List macSHA512Aliases = createAliasesWithOid(macOidBase + "11"); - // reuse attribute map and reset before each reuse HashMap attrs = new HashMap<>(3); attrs.put("SupportedModes", "ECB"); @@ -212,8 +173,8 @@ attrs.put("SupportedKeyFormats", "RAW"); ps("Cipher", "DES", "com.sun.crypto.provider.DESCipher", null, attrs); - ps("Cipher", "DESede", "com.sun.crypto.provider.DESedeCipher", - desEdeAliases, attrs); + psA("Cipher", "DESede", "com.sun.crypto.provider.DESedeCipher", + attrs); ps("Cipher", "Blowfish", "com.sun.crypto.provider.BlowfishCipher", null, attrs); @@ -224,58 +185,58 @@ attrs.put("SupportedModes", BLOCK_MODES128); attrs.put("SupportedPaddings", BLOCK_PADS); attrs.put("SupportedKeyFormats", "RAW"); - ps("Cipher", "AES", "com.sun.crypto.provider.AESCipher$General", - aesAliases, attrs); + psA("Cipher", "AES", + "com.sun.crypto.provider.AESCipher$General", attrs); attrs.clear(); attrs.put("SupportedKeyFormats", "RAW"); - ps("Cipher", "AES_128/ECB/NoPadding", + psA("Cipher", "AES_128/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding", - createAliasesWithOid(aes128Oid+"1"), attrs); - ps("Cipher", "AES_128/CBC/NoPadding", + attrs); + psA("Cipher", "AES_128/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding", - createAliasesWithOid(aes128Oid+"2"), attrs); - ps("Cipher", "AES_128/OFB/NoPadding", + attrs); + psA("Cipher", "AES_128/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding", - createAliasesWithOid(aes128Oid+"3"), attrs); - ps("Cipher", "AES_128/CFB/NoPadding", + attrs); + psA("Cipher", "AES_128/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding", - createAliasesWithOid(aes128Oid+"4"), attrs); - ps("Cipher", "AES_128/GCM/NoPadding", + attrs); + psA("Cipher", "AES_128/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES128_GCM_NoPadding", - createAliasesWithOid(aes128Oid+"6"), attrs); + attrs); - ps("Cipher", "AES_192/ECB/NoPadding", + psA("Cipher", "AES_192/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding", - createAliasesWithOid(aes192Oid+"1"), attrs); - ps("Cipher", "AES_192/CBC/NoPadding", + attrs); + psA("Cipher", "AES_192/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding", - createAliasesWithOid(aes192Oid+"2"), attrs); - ps("Cipher", "AES_192/OFB/NoPadding", + attrs); + psA("Cipher", "AES_192/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding", - createAliasesWithOid(aes192Oid+"3"), attrs); - ps("Cipher", "AES_192/CFB/NoPadding", + attrs); + psA("Cipher", "AES_192/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding", - createAliasesWithOid(aes192Oid+"4"), attrs); - ps("Cipher", "AES_192/GCM/NoPadding", + attrs); + psA("Cipher", "AES_192/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES192_GCM_NoPadding", - createAliasesWithOid(aes192Oid+"6"), attrs); + attrs); - ps("Cipher", "AES_256/ECB/NoPadding", + psA("Cipher", "AES_256/ECB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding", - createAliasesWithOid(aes256Oid+"1"), attrs); - ps("Cipher", "AES_256/CBC/NoPadding", + attrs); + psA("Cipher", "AES_256/CBC/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding", - createAliasesWithOid(aes256Oid+"2"), attrs); - ps("Cipher", "AES_256/OFB/NoPadding", + attrs); + psA("Cipher", "AES_256/OFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding", - createAliasesWithOid(aes256Oid+"3"), attrs); - ps("Cipher", "AES_256/CFB/NoPadding", + attrs); + psA("Cipher", "AES_256/CFB/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding", - createAliasesWithOid(aes256Oid+"4"), attrs); - ps("Cipher", "AES_256/GCM/NoPadding", + attrs); + psA("Cipher", "AES_256/GCM/NoPadding", "com.sun.crypto.provider.AESCipher$AES256_GCM_NoPadding", - createAliasesWithOid(aes256Oid+"6"), attrs); + attrs); attrs.clear(); attrs.put("SupportedModes", "CBC"); @@ -288,148 +249,131 @@ attrs.put("SupportedModes", "ECB"); attrs.put("SupportedPaddings", "NOPADDING"); attrs.put("SupportedKeyFormats", "RAW"); - ps("Cipher", "ARCFOUR", "com.sun.crypto.provider.ARCFOURCipher", - arcFourAliases, attrs); + psA("Cipher", "ARCFOUR", + "com.sun.crypto.provider.ARCFOURCipher", attrs); ps("Cipher", "AESWrap", "com.sun.crypto.provider.AESWrapCipher$General", null, attrs); - ps("Cipher", "AESWrap_128", + psA("Cipher", "AESWrap_128", "com.sun.crypto.provider.AESWrapCipher$AES128", - createAliasesWithOid(aes128Oid+"5"), attrs); - ps("Cipher", "AESWrap_192", + attrs); + psA("Cipher", "AESWrap_192", "com.sun.crypto.provider.AESWrapCipher$AES192", - createAliasesWithOid(aes192Oid+"5"), attrs); - ps("Cipher", "AESWrap_256", + attrs); + psA("Cipher", "AESWrap_256", "com.sun.crypto.provider.AESWrapCipher$AES256", - createAliasesWithOid(aes256Oid+"5"), attrs); + attrs); attrs.clear(); attrs.put("SupportedKeyFormats", "RAW"); ps("Cipher", "ChaCha20", "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Only", null, attrs); - ps("Cipher", "ChaCha20-Poly1305", + psA("Cipher", "ChaCha20-Poly1305", "com.sun.crypto.provider.ChaCha20Cipher$ChaCha20Poly1305", - chachaPolyAliases, attrs); + attrs); // PBES1 - ps("Cipher", "PBEWithMD5AndDES", + psA("Cipher", "PBEWithMD5AndDES", "com.sun.crypto.provider.PBEWithMD5AndDESCipher", - pkcs5MD5_DESAliases, null); + null); ps("Cipher", "PBEWithMD5AndTripleDES", - "com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher", - null, null); - ps("Cipher", "PBEWithSHA1AndDESede", + "com.sun.crypto.provider.PBEWithMD5AndTripleDESCipher"); + psA("Cipher", "PBEWithSHA1AndDESede", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndDESede", - pkcs12DESedeAliases, null); - ps("Cipher", "PBEWithSHA1AndRC2_40", + null); + psA("Cipher", "PBEWithSHA1AndRC2_40", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40", - pkcs12RC2_40Aliases, null); - ps("Cipher", "PBEWithSHA1AndRC2_128", + null); + psA("Cipher", "PBEWithSHA1AndRC2_128", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_128", - pkcs12RC2_128Aliases, null); - ps("Cipher", "PBEWithSHA1AndRC4_40", + null); + psA("Cipher", "PBEWithSHA1AndRC4_40", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_40", - pkcs12RC4_40Aliases, null); + null); - ps("Cipher", "PBEWithSHA1AndRC4_128", + psA("Cipher", "PBEWithSHA1AndRC4_128", "com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC4_128", - pkcs12RC4_128Aliases, null); + null); // PBES2 ps("Cipher", "PBEWithHmacSHA1AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_128"); ps("Cipher", "PBEWithHmacSHA224AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_128"); ps("Cipher", "PBEWithHmacSHA256AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_128"); ps("Cipher", "PBEWithHmacSHA384AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_128"); ps("Cipher", "PBEWithHmacSHA512AndAES_128", - "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_128"); ps("Cipher", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA1AndAES_256"); ps("Cipher", "PBEWithHmacSHA224AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA224AndAES_256"); ps("Cipher", "PBEWithHmacSHA256AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256"); ps("Cipher", "PBEWithHmacSHA384AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA384AndAES_256"); ps("Cipher", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Core$HmacSHA512AndAES_256"); /* * Key(pair) Generator engines */ ps("KeyGenerator", "DES", - "com.sun.crypto.provider.DESKeyGenerator", - null, null); - ps("KeyGenerator", "DESede", + "com.sun.crypto.provider.DESKeyGenerator"); + psA("KeyGenerator", "DESede", "com.sun.crypto.provider.DESedeKeyGenerator", - desEdeAliases, null); + null); ps("KeyGenerator", "Blowfish", - "com.sun.crypto.provider.BlowfishKeyGenerator", - null, null); - ps("KeyGenerator", "AES", + "com.sun.crypto.provider.BlowfishKeyGenerator"); + psA("KeyGenerator", "AES", "com.sun.crypto.provider.AESKeyGenerator", - aesAliases, null); + null); ps("KeyGenerator", "RC2", - "com.sun.crypto.provider.KeyGeneratorCore$RC2KeyGenerator", - null, null); - ps("KeyGenerator", "ARCFOUR", + "com.sun.crypto.provider.KeyGeneratorCore$RC2KeyGenerator"); + psA("KeyGenerator", "ARCFOUR", "com.sun.crypto.provider.KeyGeneratorCore$ARCFOURKeyGenerator", - arcFourAliases, null); + null); ps("KeyGenerator", "ChaCha20", - "com.sun.crypto.provider.KeyGeneratorCore$ChaCha20KeyGenerator", - null, null); + "com.sun.crypto.provider.KeyGeneratorCore$ChaCha20KeyGenerator"); ps("KeyGenerator", "HmacMD5", - "com.sun.crypto.provider.HmacMD5KeyGenerator", - null, null); + "com.sun.crypto.provider.HmacMD5KeyGenerator"); - ps("KeyGenerator", "HmacSHA1", - "com.sun.crypto.provider.HmacSHA1KeyGenerator", - macSHA1Aliases, null); - ps("KeyGenerator", "HmacSHA224", + psA("KeyGenerator", "HmacSHA1", + "com.sun.crypto.provider.HmacSHA1KeyGenerator", null); + psA("KeyGenerator", "HmacSHA224", "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA224", - macSHA224Aliases, null); - ps("KeyGenerator", "HmacSHA256", + null); + psA("KeyGenerator", "HmacSHA256", "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA256", - macSHA256Aliases, null); - ps("KeyGenerator", "HmacSHA384", + null); + psA("KeyGenerator", "HmacSHA384", "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA384", - macSHA384Aliases, null); - ps("KeyGenerator", "HmacSHA512", + null); + psA("KeyGenerator", "HmacSHA512", "com.sun.crypto.provider.KeyGeneratorCore$HmacSHA2KG$SHA512", - macSHA512Aliases, null); + null); - ps("KeyPairGenerator", "DiffieHellman", + psA("KeyPairGenerator", "DiffieHellman", "com.sun.crypto.provider.DHKeyPairGenerator", - diffieHellmanAliases, null); + null); /* * Algorithm parameter generation engines */ - ps("AlgorithmParameterGenerator", + psA("AlgorithmParameterGenerator", "DiffieHellman", "com.sun.crypto.provider.DHParameterGenerator", - diffieHellmanAliases, null); + null); /* * Key Agreement engines @@ -437,142 +381,120 @@ attrs.clear(); attrs.put("SupportedKeyClasses", "javax.crypto.interfaces.DHPublicKey" + "|javax.crypto.interfaces.DHPrivateKey"); - ps("KeyAgreement", "DiffieHellman", + psA("KeyAgreement", "DiffieHellman", "com.sun.crypto.provider.DHKeyAgreement", - diffieHellmanAliases, attrs); + attrs); /* * Algorithm Parameter engines */ - ps("AlgorithmParameters", "DiffieHellman", - "com.sun.crypto.provider.DHParameters", - diffieHellmanAliases, null); + psA("AlgorithmParameters", "DiffieHellman", + "com.sun.crypto.provider.DHParameters", null); ps("AlgorithmParameters", "DES", - "com.sun.crypto.provider.DESParameters", - null, null); + "com.sun.crypto.provider.DESParameters"); - ps("AlgorithmParameters", "DESede", - "com.sun.crypto.provider.DESedeParameters", - desEdeAliases, null); + psA("AlgorithmParameters", "DESede", + "com.sun.crypto.provider.DESedeParameters", null); - ps("AlgorithmParameters", "PBEWithMD5AndDES", + psA("AlgorithmParameters", "PBEWithMD5AndDES", "com.sun.crypto.provider.PBEParameters", - pkcs5MD5_DESAliases, null); + null); ps("AlgorithmParameters", "PBEWithMD5AndTripleDES", - "com.sun.crypto.provider.PBEParameters", - null, null); + "com.sun.crypto.provider.PBEParameters"); - ps("AlgorithmParameters", "PBEWithSHA1AndDESede", + psA("AlgorithmParameters", "PBEWithSHA1AndDESede", "com.sun.crypto.provider.PBEParameters", - pkcs12DESedeAliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC2_40", + psA("AlgorithmParameters", "PBEWithSHA1AndRC2_40", "com.sun.crypto.provider.PBEParameters", - pkcs12RC2_40Aliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC2_128", + psA("AlgorithmParameters", "PBEWithSHA1AndRC2_128", "com.sun.crypto.provider.PBEParameters", - pkcs12RC2_128Aliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC4_40", + psA("AlgorithmParameters", "PBEWithSHA1AndRC4_40", "com.sun.crypto.provider.PBEParameters", - pkcs12RC4_40Aliases, null); + null); - ps("AlgorithmParameters", "PBEWithSHA1AndRC4_128", + psA("AlgorithmParameters", "PBEWithSHA1AndRC4_128", "com.sun.crypto.provider.PBEParameters", - pkcs12RC4_128Aliases, null); + null); - ps("AlgorithmParameters", "PBES2", + psA("AlgorithmParameters", "PBES2", "com.sun.crypto.provider.PBES2Parameters$General", - pkcs5PBES2Aliases, null); + null); ps("AlgorithmParameters", "PBEWithHmacSHA1AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA224AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA256AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA384AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA512AndAES_128", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_128", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_128"); ps("AlgorithmParameters", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA1AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA224AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA224AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA256AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA384AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA384AndAES_256"); ps("AlgorithmParameters", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_256", - null, null); + "com.sun.crypto.provider.PBES2Parameters$HmacSHA512AndAES_256"); ps("AlgorithmParameters", "Blowfish", - "com.sun.crypto.provider.BlowfishParameters", - null, null); + "com.sun.crypto.provider.BlowfishParameters"); - ps("AlgorithmParameters", "AES", - "com.sun.crypto.provider.AESParameters", - aesAliases, null); + psA("AlgorithmParameters", "AES", + "com.sun.crypto.provider.AESParameters", null); ps("AlgorithmParameters", "GCM", - "com.sun.crypto.provider.GCMParameters", - null, null); + "com.sun.crypto.provider.GCMParameters"); ps("AlgorithmParameters", "RC2", - "com.sun.crypto.provider.RC2Parameters", - null, null); + "com.sun.crypto.provider.RC2Parameters"); ps("AlgorithmParameters", "OAEP", - "com.sun.crypto.provider.OAEPParameters", - null, null); + "com.sun.crypto.provider.OAEPParameters"); - ps("AlgorithmParameters", "ChaCha20-Poly1305", - "com.sun.crypto.provider.ChaCha20Poly1305Parameters", - chachaPolyAliases, null); + psA("AlgorithmParameters", "ChaCha20-Poly1305", + "com.sun.crypto.provider.ChaCha20Poly1305Parameters", null); /* * Key factories */ - ps("KeyFactory", "DiffieHellman", + psA("KeyFactory", "DiffieHellman", "com.sun.crypto.provider.DHKeyFactory", - diffieHellmanAliases, null); + null); /* * Secret-key factories */ ps("SecretKeyFactory", "DES", - "com.sun.crypto.provider.DESKeyFactory", - null, null); + "com.sun.crypto.provider.DESKeyFactory"); - ps("SecretKeyFactory", "DESede", - "com.sun.crypto.provider.DESedeKeyFactory", - desEdeAliases, null); + psA("SecretKeyFactory", "DESede", + "com.sun.crypto.provider.DESedeKeyFactory", null); - ps("SecretKeyFactory", "PBEWithMD5AndDES", + psA("SecretKeyFactory", "PBEWithMD5AndDES", "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES", - pkcs5MD5_DESAliases, null); + null); /* * Internal in-house crypto algorithm used for @@ -581,85 +503,70 @@ * algorithm. */ ps("SecretKeyFactory", "PBEWithMD5AndTripleDES", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndTripleDES"); - ps("SecretKeyFactory", "PBEWithSHA1AndDESede", + psA("SecretKeyFactory", "PBEWithSHA1AndDESede", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndDESede", - pkcs12DESedeAliases, null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC2_40", + psA("SecretKeyFactory", "PBEWithSHA1AndRC2_40", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_40", - pkcs12RC2_40Aliases, null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC2_128", + psA("SecretKeyFactory", "PBEWithSHA1AndRC2_128", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC2_128", - pkcs12RC2_128Aliases, null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC4_40", + psA("SecretKeyFactory", "PBEWithSHA1AndRC4_40", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_40", - pkcs12RC4_40Aliases,null); + null); - ps("SecretKeyFactory", "PBEWithSHA1AndRC4_128", + psA("SecretKeyFactory", "PBEWithSHA1AndRC4_128", "com.sun.crypto.provider.PBEKeyFactory$PBEWithSHA1AndRC4_128", - pkcs12RC4_128Aliases, null); + null); ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_128", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_128"); ps("SecretKeyFactory", "PBEWithHmacSHA1AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA1AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA224AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA224AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA256AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA256AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA384AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA384AndAES_256"); ps("SecretKeyFactory", "PBEWithHmacSHA512AndAES_256", - "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256", - null, null); + "com.sun.crypto.provider.PBEKeyFactory$PBEWithHmacSHA512AndAES_256"); // PBKDF2 - ps("SecretKeyFactory", "PBKDF2WithHmacSHA1", + psA("SecretKeyFactory", "PBKDF2WithHmacSHA1", "com.sun.crypto.provider.PBKDF2Core$HmacSHA1", - pkcs5PBKDF2Aliases, null); + null); ps("SecretKeyFactory", "PBKDF2WithHmacSHA224", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA224", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA224"); ps("SecretKeyFactory", "PBKDF2WithHmacSHA256", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA256", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA256"); ps("SecretKeyFactory", "PBKDF2WithHmacSHA384", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA384", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA384"); ps("SecretKeyFactory", "PBKDF2WithHmacSHA512", - "com.sun.crypto.provider.PBKDF2Core$HmacSHA512", - null, null); + "com.sun.crypto.provider.PBKDF2Core$HmacSHA512"); /* * MAC @@ -667,23 +574,20 @@ attrs.clear(); attrs.put("SupportedKeyFormats", "RAW"); ps("Mac", "HmacMD5", "com.sun.crypto.provider.HmacMD5", null, attrs); - ps("Mac", "HmacSHA1", "com.sun.crypto.provider.HmacSHA1", - macSHA1Aliases, attrs); - ps("Mac", "HmacSHA224", "com.sun.crypto.provider.HmacCore$HmacSHA224", - macSHA224Aliases, attrs); - ps("Mac", "HmacSHA256", "com.sun.crypto.provider.HmacCore$HmacSHA256", - macSHA256Aliases, attrs); - ps("Mac", "HmacSHA384", "com.sun.crypto.provider.HmacCore$HmacSHA384", - macSHA384Aliases, attrs); - ps("Mac", "HmacSHA512", "com.sun.crypto.provider.HmacCore$HmacSHA512", - macSHA512Aliases, attrs); - // TODO: aliases with OIDs - ps("Mac", "HmacSHA512/224", - "com.sun.crypto.provider.HmacCore$HmacSHA512_224", - null, attrs); - ps("Mac", "HmacSHA512/256", - "com.sun.crypto.provider.HmacCore$HmacSHA512_256", - null, attrs); + psA("Mac", "HmacSHA1", "com.sun.crypto.provider.HmacSHA1", + attrs); + psA("Mac", "HmacSHA224", + "com.sun.crypto.provider.HmacCore$HmacSHA224", attrs); + psA("Mac", "HmacSHA256", + "com.sun.crypto.provider.HmacCore$HmacSHA256", attrs); + psA("Mac", "HmacSHA384", + "com.sun.crypto.provider.HmacCore$HmacSHA384", attrs); + psA("Mac", "HmacSHA512", + "com.sun.crypto.provider.HmacCore$HmacSHA512", attrs); + psA("Mac", "HmacSHA512/224", + "com.sun.crypto.provider.HmacCore$HmacSHA512_224", attrs); + psA("Mac", "HmacSHA512/256", + "com.sun.crypto.provider.HmacCore$HmacSHA512_256", attrs); ps("Mac", "HmacPBESHA1", "com.sun.crypto.provider.HmacPKCS12PBECore$HmacPKCS12PBE_SHA1", null, attrs); @@ -727,8 +631,7 @@ * KeyStore */ ps("KeyStore", "JCEKS", - "com.sun.crypto.provider.JceKeyStore", - null, null); + "com.sun.crypto.provider.JceKeyStore"); /* * SSL/TLS mechanisms @@ -739,24 +642,22 @@ * mechanisms, and it will cause calls to come here. */ ps("KeyGenerator", "SunTlsPrf", - "com.sun.crypto.provider.TlsPrfGenerator$V10", - null, null); + "com.sun.crypto.provider.TlsPrfGenerator$V10"); ps("KeyGenerator", "SunTls12Prf", - "com.sun.crypto.provider.TlsPrfGenerator$V12", - null, null); + "com.sun.crypto.provider.TlsPrfGenerator$V12"); ps("KeyGenerator", "SunTlsMasterSecret", "com.sun.crypto.provider.TlsMasterSecretGenerator", - createAliases("SunTls12MasterSecret", - "SunTlsExtendedMasterSecret"), null); + List.of("SunTls12MasterSecret", "SunTlsExtendedMasterSecret"), + null); ps("KeyGenerator", "SunTlsKeyMaterial", "com.sun.crypto.provider.TlsKeyMaterialGenerator", - createAliases("SunTls12KeyMaterial"), null); + List.of("SunTls12KeyMaterial"), null); ps("KeyGenerator", "SunTlsRsaPremasterSecret", "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator", - createAliases("SunTls12RsaPremasterSecret"), null); + List.of("SunTls12RsaPremasterSecret"), null); } // Return the instance of this class or create one if needed. diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, 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 @@ -25,6 +25,9 @@ package com.sun.crypto.provider; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.*; import java.security.spec.AlgorithmParameterSpec; @@ -61,11 +64,11 @@ @SuppressWarnings("deprecation") protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { - if (params instanceof TlsMasterSecretParameterSpec == false) { + if (!(params instanceof TlsMasterSecretParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } this.spec = (TlsMasterSecretParameterSpec)params; - if ("RAW".equals(spec.getPremasterSecret().getFormat()) == false) { + if (!"RAW".equals(spec.getPremasterSecret().getFormat())) { throw new InvalidAlgorithmParameterException( "Key format must be RAW"); } @@ -185,6 +188,21 @@ return key.clone(); } - } + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if ((key == null) || (key.length == 0)) { + throw new InvalidObjectException("TlsMasterSecretKey is null"); + } + key = key.clone(); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java 2023-10-06 05:33:33.000000000 +0000 @@ -61,7 +61,7 @@ // Resets the engine and frees all resources. // Returns total number of bytes consumed by the engine. - private synchronized native long finish(); + synchronized native long finish(); // Setting state in the unpacker. protected synchronized native boolean setOption(String opt, String value); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -116,6 +116,11 @@ } catch (UnsatisfiedLinkError | NoClassDefFoundError ex) { // failover to java implementation (new DoUnpack()).run(in0, out); + } finally { + if (_nunp != null) { + // Free up native memory and JNI handles to prevent leaks + ((NativeUnpack) _nunp).finish(); + } } in0.close(); Utils.markJarFile(out); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/net/URI.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/net/URI.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/net/URI.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/net/URI.java 2023-10-06 05:33:33.000000000 +0000 @@ -3193,6 +3193,7 @@ boolean serverChars; boolean regChars; + boolean skipParseException; if (scan(p, n, "]") > p) { // contains a literal IPv6 address, therefore % is allowed @@ -3208,15 +3209,28 @@ return n; } + // When parsing a URI, skip creating exception objects if the server-based + // authority is not required and the registry parse is successful. + // + skipParseException = (!requireServerAuthority && regChars); if (serverChars) { // Might be (probably is) a server-based authority, so attempt // to parse it as such. If the attempt fails, try to treat it // as a registry-based authority. try { - q = parseServer(p, n); - if (q < n) - failExpecting("end of authority", q); - authority = input.substring(p, n); + q = parseServer(p, n, skipParseException); + if (q < n) { + if (skipParseException) { + userInfo = null; + host = null; + port = -1; + q = p; + } else { + failExpecting("end of authority", q); + } + } else { + authority = input.substring(p, n); + } } catch (URISyntaxException x) { // Undo results of failed parse userInfo = null; @@ -3254,7 +3268,7 @@ // [@][:] // - private int parseServer(int start, int n) + private int parseServer(int start, int n, boolean skipParseException) throws URISyntaxException { int p = start; @@ -3294,7 +3308,7 @@ } else { q = parseIPv4Address(p, n); if (q <= p) - q = parseHostname(p, n); + q = parseHostname(p, n, skipParseException); p = q; } @@ -3311,7 +3325,10 @@ } p = q; } + } else if (p < n && skipParseException) { + return p; } + if (p < n) failExpecting("port number", p); @@ -3416,7 +3433,7 @@ // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum // toplabel = alpha | alpha *( alphanum | "-" ) alphanum // - private int parseHostname(int start, int n) + private int parseHostname(int start, int n, boolean skipParseException) throws URISyntaxException { int p = start; @@ -3444,9 +3461,12 @@ p = q; } while (p < n); - if ((p < n) && !at(p, n, ':')) + if ((p < n) && !at(p, n, ':')) { + if (skipParseException) { + return p; + } fail("Illegal character in hostname", p); - + } if (l < 0) failExpecting("hostname", start); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -309,7 +309,7 @@ * @param size the size (number of bits). */ public final void init(int size) { - paramGenSpi.engineInit(size, JCAUtil.getSecureRandom()); + paramGenSpi.engineInit(size, JCAUtil.getDefSecureRandom()); } /** @@ -340,7 +340,7 @@ */ public final void init(AlgorithmParameterSpec genParamSpec) throws InvalidAlgorithmParameterException { - paramGenSpi.engineInit(genParamSpec, JCAUtil.getSecureRandom()); + paramGenSpi.engineInit(genParamSpec, JCAUtil.getDefSecureRandom()); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/CertificateFactory.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/CertificateFactory.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/CertificateFactory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/CertificateFactory.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,14 +26,14 @@ package java.security.cert; import java.io.InputStream; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Objects; import java.security.Provider; import java.security.Security; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; import sun.security.jca.*; import sun.security.jca.GetInstance.Instance; @@ -352,7 +352,9 @@ public final Certificate generateCertificate(InputStream inStream) throws CertificateException { - return certFacSpi.engineGenerateCertificate(inStream); + Certificate c = certFacSpi.engineGenerateCertificate(inStream); + JCAUtil.tryCommitCertEvent(c); + return c; } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -243,7 +243,7 @@ boolean critical = ois.readBoolean(); byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt()); Extension ext = sun.security.x509.Extension.newExtension - (new ObjectIdentifier(oid), critical, extVal); + (ObjectIdentifier.of(oid), critical, extVal); extensions.put(oid, ext); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/CertPathHelperImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -25,12 +25,10 @@ package java.security.cert; -import java.util.*; +import java.util.Date; import sun.security.provider.certpath.CertPathHelper; -import sun.security.x509.GeneralNameInterface; - /** * Helper class that allows the Sun CertPath provider to access * implementation dependent APIs in CertPath framework. @@ -55,11 +53,6 @@ } } - protected void implSetPathToNames(X509CertSelector sel, - Set names) { - sel.setPathToNamesInternal(names); - } - protected void implSetDateAndTime(X509CRLSelector sel, Date date, long skew) { sel.setDateAndTime(date, skew); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/X509CertSelector.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/X509CertSelector.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/cert/X509CertSelector.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/cert/X509CertSelector.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, 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 @@ -31,11 +31,7 @@ import java.util.*; import javax.security.auth.x500.X500Principal; -import sun.security.util.HexDumpEncoder; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; import sun.security.x509.*; /** @@ -88,11 +84,7 @@ private static final Debug debug = Debug.getInstance("certpath"); private static final ObjectIdentifier ANY_EXTENDED_KEY_USAGE = - ObjectIdentifier.newInternal(new int[] {2, 5, 29, 37, 0}); - - static { - CertPathHelperImpl.initialize(); - } + ObjectIdentifier.of(KnownOIDs.anyExtendedKeyUsage); private BigInteger serialNumber; private X500Principal issuer; @@ -506,7 +498,7 @@ if (oid == null) { subjectPublicKeyAlgID = null; } else { - subjectPublicKeyAlgID = new ObjectIdentifier(oid); + subjectPublicKeyAlgID = ObjectIdentifier.of(oid); } } @@ -622,7 +614,7 @@ Collections.unmodifiableSet(new HashSet<>(keyPurposeSet)); keyPurposeOIDSet = new HashSet<>(); for (String s : this.keyPurposeSet) { - keyPurposeOIDSet.add(new ObjectIdentifier(s)); + keyPurposeOIDSet.add(ObjectIdentifier.of(s)); } } } @@ -1105,8 +1097,8 @@ if (!(o instanceof String)) { throw new IOException("non String in certPolicySet"); } - polIdVector.add(new CertificatePolicyId(new ObjectIdentifier( - (String)o))); + polIdVector.add(new CertificatePolicyId + (ObjectIdentifier.of((String)o))); } // If everything went OK, make the changes policySet = tempSet; @@ -1177,14 +1169,6 @@ } } - // called from CertPathHelper - void setPathToNamesInternal(Set names) { - // set names to non-null dummy value - // this breaks getPathToNames() - pathToNames = Collections.>emptySet(); - pathToGeneralNames = names; - } - /** * Adds a name to the pathToNames criterion. The {@code X509Certificate} * must not include name constraints that would prohibit building a diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/CodeSigner.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/CodeSigner.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/CodeSigner.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/CodeSigner.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, 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 @@ -156,9 +156,9 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("("); - sb.append("Signer: " + signerCertPath.getCertificates().get(0)); + sb.append("Signer: ").append(signerCertPath.getCertificates().get(0)); if (timestamp != null) { - sb.append("timestamp: " + timestamp); + sb.append("timestamp: ").append(timestamp); } sb.append(")"); return sb.toString(); @@ -166,8 +166,11 @@ // Explicitly reset hash code value to -1 private void readObject(ObjectInputStream ois) - throws IOException, ClassNotFoundException { - ois.defaultReadObject(); - myhash = -1; + throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + if (signerCertPath == null) { + throw new InvalidObjectException("signerCertPath is null"); + } + myhash = -1; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/KeyPairGenerator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/KeyPairGenerator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/KeyPairGenerator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/KeyPairGenerator.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -373,7 +373,7 @@ * supported by this KeyPairGenerator object. */ public void initialize(int keysize) { - initialize(keysize, JCAUtil.getSecureRandom()); + initialize(keysize, JCAUtil.getDefSecureRandom()); } /** @@ -433,7 +433,7 @@ */ public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { - initialize(params, JCAUtil.getSecureRandom()); + initialize(params, JCAUtil.getDefSecureRandom()); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/PKCS12Attribute.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/PKCS12Attribute.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/PKCS12Attribute.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/PKCS12Attribute.java 2023-10-06 05:33:33.000000000 +0000 @@ -76,7 +76,7 @@ // Validate name ObjectIdentifier type; try { - type = new ObjectIdentifier(name); + type = ObjectIdentifier.of(name); } catch (IOException e) { throw new IllegalArgumentException("Incorrect format: name", e); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/Security.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/Security.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/security/Security.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/security/Security.java 2023-10-06 05:33:33.000000000 +0000 @@ -47,6 +47,9 @@ * implementation-specific location, which is typically the properties file * {@code conf/security/java.security} in the Java installation directory. * + * @implNote If the properties file fails to load, the JDK implementation will + * throw an unspecified error when initializing the {@code Security} class. + * * @author Benjamin Renaud * @since 1.1 */ @@ -81,130 +84,83 @@ private static void initialize() { props = new Properties(); - boolean loadedProps = false; boolean overrideAll = false; // first load the system properties file // to determine the value of security.overridePropertiesFile File propFile = securityPropFile("java.security"); - if (propFile.exists()) { - InputStream is = null; - try { - FileInputStream fis = new FileInputStream(propFile); - is = new BufferedInputStream(fis); - props.load(is); - loadedProps = true; - - if (sdebug != null) { - sdebug.println("reading security properties file: " + - propFile); - } - } catch (IOException e) { - if (sdebug != null) { - sdebug.println("unable to load security properties from " + - propFile); - e.printStackTrace(); - } - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException ioe) { - if (sdebug != null) { - sdebug.println("unable to close input stream"); - } - } - } - } + boolean success = loadProps(propFile, null, false); + if (!success) { + throw new InternalError("Error loading java.security file"); } if ("true".equalsIgnoreCase(props.getProperty ("security.overridePropertiesFile"))) { String extraPropFile = System.getProperty - ("java.security.properties"); + ("java.security.properties"); if (extraPropFile != null && extraPropFile.startsWith("=")) { overrideAll = true; extraPropFile = extraPropFile.substring(1); } + loadProps(null, extraPropFile, overrideAll); + } + } - if (overrideAll) { - props = new Properties(); - if (sdebug != null) { - sdebug.println - ("overriding other security properties files!"); + private static boolean loadProps(File masterFile, String extraPropFile, boolean overrideAll) { + InputStream is = null; + try { + if (masterFile != null && masterFile.exists()) { + is = new FileInputStream(masterFile); + } else if (extraPropFile != null) { + extraPropFile = PropertyExpander.expand(extraPropFile); + File propFile = new File(extraPropFile); + URL propURL; + if (propFile.exists()) { + propURL = new URL + ("file:" + propFile.getCanonicalPath()); + } else { + propURL = new URL(extraPropFile); } - } - - // now load the user-specified file so its values - // will win if they conflict with the earlier values - if (extraPropFile != null) { - BufferedInputStream bis = null; - try { - URL propURL; - - extraPropFile = PropertyExpander.expand(extraPropFile); - propFile = new File(extraPropFile); - if (propFile.exists()) { - propURL = new URL - ("file:" + propFile.getCanonicalPath()); - } else { - propURL = new URL(extraPropFile); - } - bis = new BufferedInputStream(propURL.openStream()); - props.load(bis); - loadedProps = true; - if (sdebug != null) { - sdebug.println("reading security properties file: " + - propURL); - if (overrideAll) { - sdebug.println - ("overriding other security properties files!"); - } - } - } catch (Exception e) { + is = propURL.openStream(); + if (overrideAll) { + props = new Properties(); if (sdebug != null) { sdebug.println - ("unable to load security properties from " + - extraPropFile); - e.printStackTrace(); - } - } finally { - if (bis != null) { - try { - bis.close(); - } catch (IOException ioe) { - if (sdebug != null) { - sdebug.println("unable to close input stream"); - } - } + ("overriding other security properties files!"); } } + } else { + // unexpected + return false; } - } - - if (!loadedProps) { - initializeStatic(); + props.load(is); + if (sdebug != null) { + // ExceptionInInitializerError if masterFile.getName() is + // called here (NPE!). Leave as is (and few lines down) + sdebug.println("reading security properties file: " + + masterFile == null ? extraPropFile : "java.security"); + } + return true; + } catch (IOException | PropertyExpander.ExpandException e) { if (sdebug != null) { - sdebug.println("unable to load security properties " + - "-- using defaults"); + sdebug.println("unable to load security properties from " + + masterFile == null ? extraPropFile : "java.security"); + e.printStackTrace(); + } + return false; + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException ioe) { + if (sdebug != null) { + sdebug.println("unable to close input stream"); + } + } } } - - } - - /* - * Initialize to default values, if /lib/java.security - * is not found. - */ - private static void initializeStatic() { - props.put("security.provider.1", "sun.security.provider.Sun"); - props.put("security.provider.2", "sun.security.rsa.SunRsaSign"); - props.put("security.provider.3", "com.sun.net.ssl.internal.ssl.Provider"); - props.put("security.provider.4", "com.sun.crypto.provider.SunJCE"); - props.put("security.provider.5", "sun.security.jgss.SunProvider"); - props.put("security.provider.6", "com.sun.security.sasl.Provider"); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java 2023-10-06 05:33:33.000000000 +0000 @@ -1807,6 +1807,8 @@ * interrupted. */ private Object waitingGet(boolean interruptible) { + if (interruptible && Thread.interrupted()) + return null; Signaller q = null; boolean queued = false; Object r; @@ -1818,25 +1820,25 @@ } else if (!queued) queued = tryPushStack(q); + else if (interruptible && q.interrupted) { + q.thread = null; + cleanStack(); + return null; + } else { try { ForkJoinPool.managedBlock(q); } catch (InterruptedException ie) { // currently cannot happen q.interrupted = true; } - if (q.interrupted && interruptible) - break; } } - if (q != null && queued) { + if (q != null) { q.thread = null; - if (!interruptible && q.interrupted) + if (q.interrupted) Thread.currentThread().interrupt(); - if (r == null) - cleanStack(); } - if (r != null || (r = result) != null) - postComplete(); + postComplete(); return r; } @@ -1845,45 +1847,49 @@ * throws TimeoutException on timeout. */ private Object timedGet(long nanos) throws TimeoutException { - if (Thread.interrupted()) - return null; - if (nanos > 0L) { - long d = System.nanoTime() + nanos; - long deadline = (d == 0L) ? 1L : d; // avoid 0 - Signaller q = null; - boolean queued = false; - Object r; - while ((r = result) == null) { // similar to untimed - if (q == null) { - q = new Signaller(true, nanos, deadline); - if (Thread.currentThread() instanceof ForkJoinWorkerThread) - ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q); - } - else if (!queued) - queued = tryPushStack(q); - else if (q.nanos <= 0L) - break; - else { - try { - ForkJoinPool.managedBlock(q); - } catch (InterruptedException ie) { - q.interrupted = true; - } - if (q.interrupted) - break; - } + long d = System.nanoTime() + nanos; + long deadline = (d == 0L) ? 1L : d; // avoid 0 + boolean interrupted = false, queued = false; + Signaller q = null; + Object r = null; + for (;;) { // order of checking interrupt, result, timeout matters + if (interrupted || (interrupted = Thread.interrupted())) + break; + else if ((r = result) != null) + break; + else if (nanos <= 0L) + break; + else if (q == null) { + q = new Signaller(true, nanos, deadline); + if (Thread.currentThread() instanceof ForkJoinWorkerThread) + ForkJoinPool.helpAsyncBlocker(defaultExecutor(), q); } - if (q != null && queued) { - q.thread = null; - if (r == null) - cleanStack(); + else if (!queued) + queued = tryPushStack(q); + else { + try { + ForkJoinPool.managedBlock(q); + interrupted = q.interrupted; + nanos = q.nanos; + } catch (InterruptedException ie) { + interrupted = true; + } } - if (r != null || (r = result) != null) - postComplete(); - if (r != null || (q != null && q.interrupted)) - return r; } - throw new TimeoutException(); + if (q != null) { + q.thread = null; + if (r == null) + cleanStack(); + } + if (r != null) { + if (interrupted) + Thread.currentThread().interrupt(); + postComplete(); + return r; + } else if (interrupted) + return null; + else + throw new TimeoutException(); } /* ------------- public methods -------------- */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java openjdk-lts-11.0.21+9/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java 2023-10-06 05:33:33.000000000 +0000 @@ -2852,22 +2852,20 @@ * Possibly blocks awaiting root lock. */ private final void contendedLock() { - boolean waiting = false; + Thread current = Thread.currentThread(), w; for (int s;;) { if (((s = lockState) & ~WAITER) == 0) { if (U.compareAndSetInt(this, LOCKSTATE, s, WRITER)) { - if (waiting) - waiter = null; + if (waiter == current) + U.compareAndSetObject(this, WAITERTHREAD, current, null); return; } } - else if ((s & WAITER) == 0) { - if (U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER)) { - waiting = true; - waiter = Thread.currentThread(); - } - } - else if (waiting) + else if ((s & WAITER) == 0) + U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER); + else if ((w = waiter) == null) + U.compareAndSetObject(this, WAITERTHREAD, null, current); + else if (w == current) LockSupport.park(this); } } @@ -3287,6 +3285,8 @@ private static final Unsafe U = Unsafe.getUnsafe(); private static final long LOCKSTATE = U.objectFieldOffset(TreeBin.class, "lockState"); + private static final long WAITERTHREAD + = U.objectFieldOffset(TreeBin.class, "waiter"); } /* ----------------Table Traversal -------------- */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/Cipher.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/Cipher.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/Cipher.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/Cipher.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1220,7 +1220,7 @@ * by the underlying {@code CipherSpi}. */ public final void init(int opmode, Key key) throws InvalidKeyException { - init(opmode, key, JCAUtil.getSecureRandom()); + init(opmode, key, JCAUtil.getDefSecureRandom()); } /** @@ -1361,7 +1361,7 @@ public final void init(int opmode, Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { - init(opmode, key, params, JCAUtil.getSecureRandom()); + init(opmode, key, params, JCAUtil.getDefSecureRandom()); } /** @@ -1504,7 +1504,7 @@ public final void init(int opmode, Key key, AlgorithmParameters params) throws InvalidKeyException, InvalidAlgorithmParameterException { - init(opmode, key, params, JCAUtil.getSecureRandom()); + init(opmode, key, params, JCAUtil.getDefSecureRandom()); } /** @@ -1652,7 +1652,7 @@ public final void init(int opmode, Certificate certificate) throws InvalidKeyException { - init(opmode, certificate, JCAUtil.getSecureRandom()); + init(opmode, certificate, JCAUtil.getDefSecureRandom()); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/KeyAgreement.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/KeyAgreement.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/KeyAgreement.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/KeyAgreement.java 2023-10-06 05:33:33.000000000 +0000 @@ -446,7 +446,7 @@ * has an incompatible algorithm type. */ public final void init(Key key) throws InvalidKeyException { - init(key, JCAUtil.getSecureRandom()); + init(key, JCAUtil.getDefSecureRandom()); } /** @@ -514,7 +514,7 @@ public final void init(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { - init(key, params, JCAUtil.getSecureRandom()); + init(key, params, JCAUtil.getDefSecureRandom()); } private String getProviderName() { diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/KeyGenerator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/KeyGenerator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/KeyGenerator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/KeyGenerator.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -450,7 +450,7 @@ public final void init(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { - init(params, JCAUtil.getSecureRandom()); + init(params, JCAUtil.getDefSecureRandom()); } /** @@ -514,7 +514,7 @@ * supported. */ public final void init(int keysize) { - init(keysize, JCAUtil.getSecureRandom()); + init(keysize, JCAUtil.getDefSecureRandom()); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/crypto/spec/SecretKeySpec.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. * 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,9 @@ package javax.crypto.spec; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.MessageDigest; import java.security.spec.KeySpec; import java.util.Locale; @@ -232,4 +235,25 @@ return MessageDigest.isEqual(this.key, thatKey); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + + if (key == null || algorithm == null) { + throw new InvalidObjectException("Missing argument"); + } + + this.key = key.clone(); + if (key.length == 0) { + throw new InvalidObjectException("Invalid key length"); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/net/ssl/SSLContextSpi.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/net/ssl/SSLContextSpi.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/net/ssl/SSLContextSpi.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/net/ssl/SSLContextSpi.java 2023-10-06 05:33:33.000000000 +0000 @@ -210,10 +210,9 @@ */ protected SSLParameters engineGetSupportedSSLParameters() { SSLSocket socket = getDefaultSocket(); - SSLParameters params = new SSLParameters(); + SSLParameters params = socket.getSSLParameters(); params.setCipherSuites(socket.getSupportedCipherSuites()); params.setProtocols(socket.getSupportedProtocols()); return params; } - } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/security/auth/callback/ChoiceCallback.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/security/auth/callback/ChoiceCallback.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/security/auth/callback/ChoiceCallback.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/security/auth/callback/ChoiceCallback.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,10 @@ package javax.security.auth.callback; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; + /** *

Underlying security services instantiate and pass a * {@code ChoiceCallback} to the {@code handle} @@ -42,7 +46,7 @@ * @serial * @since 1.4 */ - private String prompt; + private final String prompt; /** * @serial the list of choices * @since 1.4 @@ -52,13 +56,13 @@ * @serial the choice to be used as the default choice * @since 1.4 */ - private int defaultChoice; + private final int defaultChoice; /** * @serial whether multiple selections are allowed from the list of * choices * @since 1.4 */ - private boolean multipleSelectionsAllowed; + private final boolean multipleSelectionsAllowed; /** * @serial the selected choices, represented as indexes into the * {@code choices} list. @@ -71,7 +75,6 @@ * a list of choices, a default choice, and a boolean specifying * whether or not multiple selections from the list of choices are allowed. * - * * @param prompt the prompt used to describe the list of choices. * * @param choices the list of choices. @@ -103,15 +106,15 @@ defaultChoice < 0 || defaultChoice >= choices.length) throw new IllegalArgumentException(); + this.prompt = prompt; + this.defaultChoice = defaultChoice; + this.multipleSelectionsAllowed = multipleSelectionsAllowed; + + this.choices = choices.clone(); for (int i = 0; i < choices.length; i++) { if (choices[i] == null || choices[i].isEmpty()) throw new IllegalArgumentException(); } - - this.prompt = prompt; - this.choices = choices; - this.defaultChoice = defaultChoice; - this.multipleSelectionsAllowed = multipleSelectionsAllowed; } /** @@ -129,7 +132,7 @@ * @return the list of choices. */ public String[] getChoices() { - return choices; + return choices.clone(); } /** @@ -180,7 +183,7 @@ public void setSelectedIndexes(int[] selections) { if (!multipleSelectionsAllowed) throw new UnsupportedOperationException(); - this.selections = selections; + this.selections = selections == null ? null : selections.clone(); } /** @@ -192,6 +195,39 @@ * @see #setSelectedIndexes */ public int[] getSelectedIndexes() { - return selections; + return selections == null ? null : selections.clone(); + } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + + if ((prompt == null) || prompt.isEmpty() || + (choices == null) || (choices.length == 0) || + (defaultChoice < 0) || (defaultChoice >= choices.length)) { + throw new InvalidObjectException( + "Missing/invalid prompt/choices"); + } + + choices = choices.clone(); + for (int i = 0; i < choices.length; i++) { + if ((choices[i] == null) || choices[i].isEmpty()) + throw new InvalidObjectException("Null/empty choices"); + } + + if (selections != null) { + selections = selections.clone(); + if (!multipleSelectionsAllowed && (selections.length != 1)) { + throw new InvalidObjectException( + "Multiple selections not allowed"); + } + } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/security/auth/callback/ConfirmationCallback.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/security/auth/callback/ConfirmationCallback.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/security/auth/callback/ConfirmationCallback.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/security/auth/callback/ConfirmationCallback.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,9 @@ package javax.security.auth.callback; +import java.io.IOException; +import java.io.ObjectInputStream; + /** *

Underlying security services instantiate and pass a * {@code ConfirmationCallback} to the {@code handle} @@ -121,26 +124,27 @@ /** ERROR message type. */ public static final int ERROR = 2; + /** * @serial * @since 1.4 */ - private String prompt; + private final String prompt; /** * @serial * @since 1.4 */ - private int messageType; + private final int messageType; /** * @serial * @since 1.4 */ - private int optionType = UNSPECIFIED_OPTION; + private final int optionType; /** * @serial * @since 1.4 */ - private int defaultOption; + private final int defaultOption; /** * @serial * @since 1.4 @@ -205,8 +209,10 @@ break; } + this.prompt = null; this.messageType = messageType; this.optionType = optionType; + this.options = null; this.defaultOption = defaultOption; } @@ -247,14 +253,16 @@ defaultOption < 0 || defaultOption >= options.length) throw new IllegalArgumentException(); + this.prompt = null; + this.messageType = messageType; + this.optionType = UNSPECIFIED_OPTION; + this.defaultOption = defaultOption; + + this.options = options.clone(); for (int i = 0; i < options.length; i++) { if (options[i] == null || options[i].isEmpty()) throw new IllegalArgumentException(); } - - this.messageType = messageType; - this.options = options; - this.defaultOption = defaultOption; } /** @@ -318,6 +326,7 @@ this.prompt = prompt; this.messageType = messageType; this.optionType = optionType; + this.options = null; this.defaultOption = defaultOption; } @@ -363,15 +372,16 @@ defaultOption < 0 || defaultOption >= options.length) throw new IllegalArgumentException(); + this.prompt = prompt; + this.messageType = messageType; + this.optionType = UNSPECIFIED_OPTION; + this.defaultOption = defaultOption; + + this.options = options.clone(); for (int i = 0; i < options.length; i++) { if (options[i] == null || options[i].isEmpty()) throw new IllegalArgumentException(); } - - this.prompt = prompt; - this.messageType = messageType; - this.options = options; - this.defaultOption = defaultOption; } /** @@ -422,7 +432,7 @@ * an {@code optionType} instead of {@code options}. */ public String[] getOptions() { - return options; + return options == null ? null : options.clone(); } /** @@ -477,4 +487,19 @@ public int getSelectedIndex() { return selection; } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (options != null) { + options = options.clone(); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/security/auth/callback/PasswordCallback.java openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/security/auth/callback/PasswordCallback.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/javax/security/auth/callback/PasswordCallback.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/javax/security/auth/callback/PasswordCallback.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,15 @@ package javax.security.auth.callback; +import java.lang.ref.Cleaner; +import java.util.Arrays; + +import jdk.internal.ref.CleanerFactory; + +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; + /** *

Underlying security services instantiate and pass a * {@code PasswordCallback} to the {@code handle} @@ -37,16 +46,20 @@ private static final long serialVersionUID = 2267422647454909926L; + private transient Cleaner.Cleanable cleanable; + /** * @serial * @since 1.4 */ - private String prompt; + private final String prompt; + /** * @serial * @since 1.4 */ - private boolean echoOn; + private final boolean echoOn; + /** * @serial * @since 1.4 @@ -105,7 +118,19 @@ * @see #getPassword */ public void setPassword(char[] password) { + // Cleanup the last buffered password copy. + if (cleanable != null) { + cleanable.clean(); + cleanable = null; + } + + // Set the retrieved password. this.inputPassword = (password == null ? null : password.clone()); + + if (this.inputPassword != null) { + cleanable = CleanerFactory.cleaner().register( + this, cleanerFor(inputPassword)); + } } /** @@ -125,9 +150,38 @@ * Clear the retrieved password. */ public void clearPassword() { + // Cleanup the last retrieved password copy. + if (cleanable != null) { + cleanable.clean(); + cleanable = null; + } + } + + private static Runnable cleanerFor(char[] password) { + return () -> { + Arrays.fill(password, ' '); + }; + } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + + if (prompt == null || prompt.isEmpty()) { + throw new InvalidObjectException("Missing prompt"); + } + if (inputPassword != null) { - for (int i = 0; i < inputPassword.length; i++) - inputPassword[i] = ' '; + inputPassword = inputPassword.clone(); + cleanable = CleanerFactory.cleaner().register( + this, cleanerFor(inputPassword)); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/jdk/internal/event/X509CertificateEvent.java openjdk-lts-11.0.21+9/src/java.base/share/classes/jdk/internal/event/X509CertificateEvent.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/jdk/internal/event/X509CertificateEvent.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/jdk/internal/event/X509CertificateEvent.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -31,6 +31,15 @@ */ public final class X509CertificateEvent extends Event { + private static final X509CertificateEvent EVENT = new X509CertificateEvent(); + + /** + * Returns {@code true} if event is enabled, {@code false} otherwise. + */ + public static boolean isTurnedOn() { + return EVENT.isEnabled(); + } + public String algorithm; public String serialNumber; public String subject; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/launcher/LauncherHelper.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/launcher/LauncherHelper.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/launcher/LauncherHelper.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/launcher/LauncherHelper.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, 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 @@ -87,6 +87,7 @@ import jdk.internal.module.Modules; import jdk.internal.platform.Container; import jdk.internal.platform.Metrics; +import sun.util.calendar.ZoneInfoFile; public final class LauncherHelper { @@ -280,6 +281,8 @@ Locale.getDefault(Category.DISPLAY).getDisplayName()); ostream.println(INDENT + "default format locale = " + Locale.getDefault(Category.FORMAT).getDisplayName()); + ostream.println(INDENT + "tzdata version = " + + ZoneInfoFile.getVersion()); printLocales(); ostream.println(); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java 2023-10-06 05:33:33.000000000 +0000 @@ -113,38 +113,45 @@ * @param url The URL contains info about the host and port * @param http The HttpClient to be cached */ - public synchronized void put(final URL url, Object obj, HttpClient http) { - boolean startThread = (keepAliveTimer == null); - if (!startThread) { - if (!keepAliveTimer.isAlive()) { - startThread = true; - } - } - if (startThread) { - clear(); - /* Unfortunately, we can't always believe the keep-alive timeout we got - * back from the server. If I'm connected through a Netscape proxy - * to a server that sent me a keep-alive - * time of 15 sec, the proxy unilaterally terminates my connection - * The robustness to get around this is in HttpClient.parseHTTP() - */ - final KeepAliveCache cache = this; - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() { - keepAliveTimer = InnocuousThread.newSystemThread("Keep-Alive-Timer", cache); - keepAliveTimer.setDaemon(true); - keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2); - keepAliveTimer.start(); - return null; + public void put(final URL url, Object obj, HttpClient http) { + // this method may need to close an HttpClient, either because + // it is not cacheable, or because the cache is at its capacity. + // In the latter case, we close the least recently used client. + // The client to close is stored in oldClient, and is closed + // after cacheLock is released. + HttpClient oldClient = null; + synchronized (this) { + boolean startThread = (keepAliveTimer == null); + if (!startThread) { + if (!keepAliveTimer.isAlive()) { + startThread = true; } - }); - } + } + if (startThread) { + clear(); + /* Unfortunately, we can't always believe the keep-alive timeout we got + * back from the server. If I'm connected through a Netscape proxy + * to a server that sent me a keep-alive + * time of 15 sec, the proxy unilaterally terminates my connection + * The robustness to get around this is in HttpClient.parseHTTP() + */ + final KeepAliveCache cache = this; + AccessController.doPrivileged(new PrivilegedAction<>() { + public Void run() { + keepAliveTimer = InnocuousThread.newSystemThread("Keep-Alive-Timer", cache); + keepAliveTimer.setDaemon(true); + keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2); + keepAliveTimer.start(); + return null; + } + }); + } - KeepAliveKey key = new KeepAliveKey(url, obj); - ClientVector v = super.get(key); + KeepAliveKey key = new KeepAliveKey(url, obj); + ClientVector v = super.get(key); - if (v == null) { - int keepAliveTimeout = http.getKeepAliveTimeout(); + if (v == null) { + int keepAliveTimeout = http.getKeepAliveTimeout(); if (keepAliveTimeout == 0) { keepAliveTimeout = getUserKeepAlive(http.getUsingProxy()); if (keepAliveTimeout == -1) { @@ -164,14 +171,19 @@ // alive, which could be 0, if the user specified 0 for the property assert keepAliveTimeout >= 0; if (keepAliveTimeout == 0) { - http.closeServer(); + oldClient = http; } else { v = new ClientVector(keepAliveTimeout * 1000); v.put(http); super.put(key, v); } - } else { - v.put(http); + } else { + oldClient = v.put(http); + } + } + // close after releasing locks + if (oldClient != null) { + oldClient.closeServer(); } } @@ -221,6 +233,7 @@ try { Thread.sleep(LIFETIME); } catch (InterruptedException e) {} + List closeList = null; // Remove all outdated HttpClients. synchronized (this) { @@ -230,15 +243,18 @@ for (KeepAliveKey key : keySet()) { ClientVector v = get(key); synchronized (v) { - KeepAliveEntry e = v.peek(); + KeepAliveEntry e = v.peekLast(); while (e != null) { if ((currentTime - e.idleStartTime) > v.nap) { - v.poll(); - e.hc.closeServer(); + v.pollLast(); + if (closeList == null) { + closeList = new ArrayList<>(); + } + closeList.add(e.hc); } else { break; } - e = v.peek(); + e = v.peekLast(); } if (v.isEmpty()) { @@ -251,6 +267,12 @@ removeVector(key); } } + // close connections outside cacheLock + if (closeList != null) { + for (HttpClient hc : closeList) { + hc.closeServer(); + } + } } while (!isEmpty()); } @@ -268,8 +290,8 @@ } } -/* FILO order for recycling HttpClients, should run in a thread - * to time them out. If > maxConns are in use, block. +/* LIFO order for reusing HttpClients. Most recent entries at the front. + * If > maxConns are in use, discard oldest. */ class ClientVector extends ArrayDeque { private static final long serialVersionUID = -8680532108106489459L; @@ -282,36 +304,37 @@ } synchronized HttpClient get() { - if (isEmpty()) { + // check the most recent connection, use if still valid + KeepAliveEntry e = peekFirst(); + if (e == null) { return null; } - // Loop until we find a connection that has not timed out - HttpClient hc = null; long currentTime = System.currentTimeMillis(); - do { - KeepAliveEntry e = pop(); - if ((currentTime - e.idleStartTime) > nap) { - e.hc.closeServer(); - } else { - hc = e.hc; - if (KeepAliveCache.logger.isLoggable(PlatformLogger.Level.FINEST)) { - String msg = "cached HttpClient was idle for " + if ((currentTime - e.idleStartTime) > nap) { + return null; // all connections stale - will be cleaned up later + } else { + pollFirst(); + if (KeepAliveCache.logger.isLoggable(PlatformLogger.Level.FINEST)) { + String msg = "cached HttpClient was idle for " + Long.toString(currentTime - e.idleStartTime); - KeepAliveCache.logger.finest(msg); - } + KeepAliveCache.logger.finest(msg); } - } while ((hc == null) && (!isEmpty())); - return hc; + return e.hc; + } } /* return a still valid, unused HttpClient */ - synchronized void put(HttpClient h) { + synchronized HttpClient put(HttpClient h) { + HttpClient staleClient = null; + assert KeepAliveCache.getMaxConnections() > 0; if (size() >= KeepAliveCache.getMaxConnections()) { - h.closeServer(); // otherwise the connection remains in limbo - } else { - push(new KeepAliveEntry(h, System.currentTimeMillis())); + // remove oldest connection + staleClient = removeLast().hc; } + addFirst(new KeepAliveEntry(h, System.currentTimeMillis())); + // close after releasing the locks + return staleClient; } /* remove an HttpClient */ @@ -339,10 +362,10 @@ } class KeepAliveKey { - private String protocol = null; - private String host = null; - private int port = 0; - private Object obj = null; // additional key, such as socketfactory + private final String protocol; + private final String host; + private final int port; + private final Object obj; // additional key, such as socketfactory /** * Constructor @@ -383,8 +406,8 @@ } class KeepAliveEntry { - HttpClient hc; - long idleStartTime; + final HttpClient hc; + final long idleStartTime; KeepAliveEntry(HttpClient hc, long idleStartTime) { this.hc = hc; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java 2023-10-06 05:33:33.000000000 +0000 @@ -517,4 +517,13 @@ s2 = new String (pw.getPassword()); s.defaultWriteObject (); } + + /** + * Releases any system or cryptographic resources. + * It is up to implementors to override disposeContext() + * to take necessary action. + */ + public void disposeContext() { + // do nothing + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java 2023-10-06 05:33:33.000000000 +0000 @@ -1953,6 +1953,12 @@ if (serverAuthKey != null) { AuthenticationInfo.endAuthRequest(serverAuthKey); } + if (proxyAuthentication != null) { + proxyAuthentication.disposeContext(); + } + if (serverAuthentication != null) { + serverAuthentication.disposeContext(); + } } } @@ -2182,6 +2188,9 @@ if (proxyAuthKey != null) { AuthenticationInfo.endAuthRequest(proxyAuthKey); } + if (proxyAuthentication != null) { + proxyAuthentication.disposeContext(); + } } // restore original request headers @@ -2428,6 +2437,7 @@ } if (ret != null) { if (!ret.setHeaders(this, p, raw)) { + ret.disposeContext(); ret = null; } } @@ -2596,6 +2606,7 @@ if (ret != null ) { if (!ret.setHeaders(this, p, raw)) { + ret.disposeContext(); ret = null; } } @@ -2622,6 +2633,7 @@ DigestAuthentication da = (DigestAuthentication) currentProxyCredentials; da.checkResponse (raw, method, getRequestURI()); + currentProxyCredentials.disposeContext(); currentProxyCredentials = null; } } @@ -2632,6 +2644,7 @@ DigestAuthentication da = (DigestAuthentication) currentServerCredentials; da.checkResponse (raw, method, url); + currentServerCredentials.disposeContext(); currentServerCredentials = null; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java 2023-10-06 05:33:33.000000000 +0000 @@ -225,6 +225,22 @@ return negotiator.nextToken(token); } + /** + * Releases any system resources and cryptographic information stored in + * the context object and invalidates the context. + */ + @Override + public void disposeContext() { + if (negotiator != null) { + try { + negotiator.disposeContext(); + } catch (IOException ioEx) { + //do not rethrow IOException + } + negotiator = null; + } + } + // MS will send a final WWW-Authenticate even if the status is already // 200 OK. The token can be fed into initSecContext() again to determine // if the server can be trusted. This is not the same concept as Digest's diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/http/Negotiator.java 2023-10-06 05:33:33.000000000 +0000 @@ -82,5 +82,7 @@ logger.finest("NegotiateAuthentication: " + e); } } + + public void disposeContext() throws IOException { }; } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java 2023-10-06 05:33:33.000000000 +0000 @@ -428,6 +428,14 @@ } } + @Override + public void closeServer() { + try { + // SSLSocket.close may block up to timeout. Make sure it's short. + serverSocket.setSoTimeout(1); + } catch (Exception e) {} + super.closeServer(); + } @Override public boolean needsTunneling() { diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/jca/JCAUtil.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/jca/JCAUtil.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/jca/JCAUtil.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/jca/JCAUtil.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,8 +26,14 @@ package sun.security.jca; import java.lang.ref.*; - import java.security.*; +import java.security.PublicKey; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; + +import jdk.internal.event.EventHelper; +import jdk.internal.event.X509CertificateEvent; +import sun.security.util.KeyUtil; /** * Collection of static utility methods used by the security framework. @@ -59,6 +65,8 @@ public static SecureRandom instance = new SecureRandom(); } + private static volatile SecureRandom def = null; + /** * Get a SecureRandom instance. This method should be used by JDK * internal code in favor of calling "new SecureRandom()". That needs to @@ -69,4 +77,69 @@ return CachedSecureRandomHolder.instance; } + // called by sun.security.jca.Providers class when provider list is changed + static void clearDefSecureRandom() { + def = null; + } + + /** + * Get the default SecureRandom instance. This method is the + * optimized version of "new SecureRandom()" which re-uses the default + * SecureRandom impl if the provider table is the same. + */ + public static SecureRandom getDefSecureRandom() { + SecureRandom result = def; + if (result == null) { + synchronized (JCAUtil.class) { + result = def; + if (result == null) { + def = result = new SecureRandom(); + } + } + } + return result; + + } + + public static void tryCommitCertEvent(Certificate cert) { + if ((X509CertificateEvent.isTurnedOn() || EventHelper.isLoggingSecurity())) { + if (cert instanceof X509Certificate) { + X509Certificate x509 = (X509Certificate) cert; + PublicKey pKey = x509.getPublicKey(); + String algId = x509.getSigAlgName(); + String serNum = x509.getSerialNumber().toString(16); + String subject = x509.getSubjectX500Principal().toString(); + String issuer = x509.getIssuerX500Principal().toString(); + String keyType = pKey.getAlgorithm(); + int length = KeyUtil.getKeySize(pKey); + int hashCode = x509.hashCode(); + long beginDate = x509.getNotBefore().getTime(); + long endDate = x509.getNotAfter().getTime(); + if (X509CertificateEvent.isTurnedOn()) { + X509CertificateEvent xce = new X509CertificateEvent(); + xce.algorithm = algId; + xce.serialNumber = serNum; + xce.subject = subject; + xce.issuer = issuer; + xce.keyType = keyType; + xce.keyLength = length; + xce.certificateId = hashCode; + xce.validFrom = beginDate; + xce.validUntil = endDate; + xce.commit(); + } + if (EventHelper.isLoggingSecurity()) { + EventHelper.logX509CertificateEvent(algId, + serNum, + subject, + issuer, + keyType, + length, + hashCode, + beginDate, + endDate); + } + } + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/jca/Providers.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/jca/Providers.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/jca/Providers.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/jca/Providers.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -150,6 +150,7 @@ } else { changeThreadProviderList(newList); } + JCAUtil.clearDefSecureRandom(); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs/ContentInfo.java 2023-10-06 05:33:33.000000000 +0000 @@ -38,50 +38,36 @@ public class ContentInfo { // pkcs7 pre-defined content types - private static int[] pkcs7 = {1, 2, 840, 113549, 1, 7}; - private static int[] data = {1, 2, 840, 113549, 1, 7, 1}; - private static int[] sdata = {1, 2, 840, 113549, 1, 7, 2}; - private static int[] edata = {1, 2, 840, 113549, 1, 7, 3}; - private static int[] sedata = {1, 2, 840, 113549, 1, 7, 4}; - private static int[] ddata = {1, 2, 840, 113549, 1, 7, 5}; - private static int[] crdata = {1, 2, 840, 113549, 1, 7, 6}; - private static int[] nsdata = {2, 16, 840, 1, 113730, 2, 5}; - // timestamp token (id-ct-TSTInfo) from RFC 3161 - private static int[] tstInfo = {1, 2, 840, 113549, 1, 9, 16, 1, 4}; + public static ObjectIdentifier PKCS7_OID = + ObjectIdentifier.of(KnownOIDs.PKCS7); + public static ObjectIdentifier DATA_OID = + ObjectIdentifier.of(KnownOIDs.Data); + public static ObjectIdentifier SIGNED_DATA_OID = + ObjectIdentifier.of(KnownOIDs.SignedData); + public static ObjectIdentifier ENVELOPED_DATA_OID = + ObjectIdentifier.of(KnownOIDs.EnvelopedData); + public static ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID = + ObjectIdentifier.of(KnownOIDs.SignedAndEnvelopedData); + public static ObjectIdentifier DIGESTED_DATA_OID = + ObjectIdentifier.of(KnownOIDs.DigestedData); + public static ObjectIdentifier ENCRYPTED_DATA_OID = + ObjectIdentifier.of(KnownOIDs.EncryptedData); + // this is for backwards-compatibility with JDK 1.1.x - private static final int[] OLD_SDATA = {1, 2, 840, 1113549, 1, 7, 2}; - private static final int[] OLD_DATA = {1, 2, 840, 1113549, 1, 7, 1}; - public static ObjectIdentifier PKCS7_OID; - public static ObjectIdentifier DATA_OID; - public static ObjectIdentifier SIGNED_DATA_OID; - public static ObjectIdentifier ENVELOPED_DATA_OID; - public static ObjectIdentifier SIGNED_AND_ENVELOPED_DATA_OID; - public static ObjectIdentifier DIGESTED_DATA_OID; - public static ObjectIdentifier ENCRYPTED_DATA_OID; - public static ObjectIdentifier OLD_SIGNED_DATA_OID; - public static ObjectIdentifier OLD_DATA_OID; - public static ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID; - public static ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID; + public static ObjectIdentifier OLD_SIGNED_DATA_OID = + ObjectIdentifier.of(KnownOIDs.JDK_OLD_SignedData); + public static ObjectIdentifier OLD_DATA_OID = + ObjectIdentifier.of(KnownOIDs.JDK_OLD_Data); - static { - PKCS7_OID = ObjectIdentifier.newInternal(pkcs7); - DATA_OID = ObjectIdentifier.newInternal(data); - SIGNED_DATA_OID = ObjectIdentifier.newInternal(sdata); - ENVELOPED_DATA_OID = ObjectIdentifier.newInternal(edata); - SIGNED_AND_ENVELOPED_DATA_OID = ObjectIdentifier.newInternal(sedata); - DIGESTED_DATA_OID = ObjectIdentifier.newInternal(ddata); - ENCRYPTED_DATA_OID = ObjectIdentifier.newInternal(crdata); - OLD_SIGNED_DATA_OID = ObjectIdentifier.newInternal(OLD_SDATA); - OLD_DATA_OID = ObjectIdentifier.newInternal(OLD_DATA); - /** - * The ASN.1 systax for the Netscape Certificate Sequence - * data type is defined - * - * here. - */ - NETSCAPE_CERT_SEQUENCE_OID = ObjectIdentifier.newInternal(nsdata); - TIMESTAMP_TOKEN_INFO_OID = ObjectIdentifier.newInternal(tstInfo); - } + // The ASN.1 systax for the Netscape Certificate Sequence data type is + // defined at: + // http://wp.netscape.com/eng/security/comm4-cert-download.html + public static ObjectIdentifier NETSCAPE_CERT_SEQUENCE_OID = + ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertSequence); + + // timestamp token (id-ct-TSTInfo) from RFC 3161 + public static ObjectIdentifier TIMESTAMP_TOKEN_INFO_OID = + ObjectIdentifier.of(KnownOIDs.TimeStampTokenInfo); ObjectIdentifier contentType; DerValue content; // OPTIONAL diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs/PKCS7.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs/PKCS7.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs/PKCS7.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs/PKCS7.java 2023-10-06 05:33:33.000000000 +0000 @@ -36,6 +36,7 @@ import java.security.cert.CertificateFactory; import java.security.*; +import sun.security.jca.JCAUtil; import sun.security.timestamp.*; import sun.security.util.*; import sun.security.x509.AlgorithmId; @@ -70,23 +71,6 @@ private Principal[] certIssuerNames; /* - * Random number generator for creating nonce values - * (Lazy initialization) - */ - private static class SecureRandomHolder { - static final SecureRandom RANDOM; - static { - SecureRandom tmp = null; - try { - tmp = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - // should not happen - } - RANDOM = tmp; - } - } - - /* * Object identifier for the timestamping key purpose. */ private static final String KP_TIMESTAMPING_OID = "1.3.6.1.5.5.7.3.8"; @@ -885,11 +869,9 @@ } // Generate a nonce - BigInteger nonce = null; - if (SecureRandomHolder.RANDOM != null) { - nonce = new BigInteger(64, SecureRandomHolder.RANDOM); - tsQuery.setNonce(nonce); - } + BigInteger nonce = new BigInteger(64, JCAUtil.getDefSecureRandom()); + tsQuery.setNonce(nonce); + tsQuery.requestCertificate(true); TSResponse tsReply = tsa.generateTimestamp(tsQuery); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -28,9 +28,7 @@ import java.io.IOException; import java.io.OutputStream; import java.security.cert.CertificateException; -import java.util.Locale; import java.util.Date; -import java.util.Hashtable; import sun.security.x509.CertificateExtensions; import sun.security.util.*; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java 2023-10-06 05:33:33.000000000 +0000 @@ -64,17 +64,11 @@ import javax.security.auth.x500.X500Principal; import sun.security.action.GetPropertyAction; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; import sun.security.pkcs.ContentInfo; -import sun.security.util.SecurityProperties; import sun.security.x509.AlgorithmId; import sun.security.pkcs.EncryptedPrivateKeyInfo; import sun.security.provider.JavaKeyStore.JKS; -import sun.security.util.KeyStoreDelegator; /** @@ -133,43 +127,42 @@ private static final int MAX_ITERATION_COUNT = 5000000; private static final int SALT_LEN = 20; - // friendlyName, localKeyId, trustedKeyUsage - private static final String[] CORE_ATTRIBUTES = { - "1.2.840.113549.1.9.20", - "1.2.840.113549.1.9.21", - "2.16.840.1.113894.746875.1.1" + private static final KnownOIDs[] CORE_ATTRIBUTES = { + KnownOIDs.FriendlyName, + KnownOIDs.LocalKeyID, + KnownOIDs.ORACLE_TrustedKeyUsage }; private static final Debug debug = Debug.getInstance("pkcs12"); - private static final int[] keyBag = {1, 2, 840, 113549, 1, 12, 10, 1, 2}; - private static final int[] certBag = {1, 2, 840, 113549, 1, 12, 10, 1, 3}; - private static final int[] secretBag = {1, 2, 840, 113549, 1, 12, 10, 1, 5}; + private static final ObjectIdentifier PKCS8ShroudedKeyBag_OID = + ObjectIdentifier.of(KnownOIDs.PKCS8ShroudedKeyBag); + private static final ObjectIdentifier CertBag_OID = + ObjectIdentifier.of(KnownOIDs.CertBag); + private static final ObjectIdentifier SecretBag_OID = + ObjectIdentifier.of(KnownOIDs.SecretBag); + + private static final ObjectIdentifier PKCS9FriendlyName_OID = + ObjectIdentifier.of(KnownOIDs.FriendlyName); + private static final ObjectIdentifier PKCS9LocalKeyId_OID = + ObjectIdentifier.of(KnownOIDs.LocalKeyID); + private static final ObjectIdentifier PKCS9CertType_OID = + ObjectIdentifier.of(KnownOIDs.CertTypeX509); + private static final ObjectIdentifier pbes2_OID = + ObjectIdentifier.of(KnownOIDs.PBES2); - private static final int[] pkcs9Name = {1, 2, 840, 113549, 1, 9, 20}; - private static final int[] pkcs9KeyId = {1, 2, 840, 113549, 1, 9, 21}; - - private static final int[] pkcs9certType = {1, 2, 840, 113549, 1, 9, 22, 1}; - - private static final int[] pbes2 = {1, 2, 840, 113549, 1, 5, 13}; - // TODO: temporary Oracle OID /* - * { joint-iso-itu-t(2) country(16) us(840) organization(1) oracle(113894) - * jdk(746875) crypto(1) id-at-trustedKeyUsage(1) } + * Temporary Oracle OID + * + * {joint-iso-itu-t(2) country(16) us(840) organization(1) + * oracle(113894) jdk(746875) crypto(1) id-at-trustedKeyUsage(1)} */ - private static final int[] TrustedKeyUsage = - {2, 16, 840, 1, 113894, 746875, 1, 1}; - private static final int[] AnyExtendedKeyUsage = {2, 5, 29, 37, 0}; - - private static final ObjectIdentifier PKCS8ShroudedKeyBag_OID; - private static final ObjectIdentifier CertBag_OID; - private static final ObjectIdentifier SecretBag_OID; - private static final ObjectIdentifier PKCS9FriendlyName_OID; - private static final ObjectIdentifier PKCS9LocalKeyId_OID; - private static final ObjectIdentifier PKCS9CertType_OID; - private static final ObjectIdentifier pbes2_OID; - private static final ObjectIdentifier TrustedKeyUsage_OID; - private static final ObjectIdentifier[] AnyUsage; + private static final ObjectIdentifier TrustedKeyUsage_OID = + ObjectIdentifier.of(KnownOIDs.ORACLE_TrustedKeyUsage); + + private static final ObjectIdentifier[] AnyUsage = new ObjectIdentifier[] { + ObjectIdentifier.of(KnownOIDs.anyExtendedKeyUsage) + }; private int counter = 0; @@ -198,23 +191,6 @@ // the source of randomness private SecureRandom random; - static { - try { - PKCS8ShroudedKeyBag_OID = new ObjectIdentifier(keyBag); - CertBag_OID = new ObjectIdentifier(certBag); - SecretBag_OID = new ObjectIdentifier(secretBag); - PKCS9FriendlyName_OID = new ObjectIdentifier(pkcs9Name); - PKCS9LocalKeyId_OID = new ObjectIdentifier(pkcs9KeyId); - PKCS9CertType_OID = new ObjectIdentifier(pkcs9certType); - pbes2_OID = new ObjectIdentifier(pbes2); - TrustedKeyUsage_OID = new ObjectIdentifier(TrustedKeyUsage); - AnyUsage = new ObjectIdentifier[]{ - new ObjectIdentifier(AnyExtendedKeyUsage)}; - } catch (IOException ioe) { - throw new AssertionError("OID not initialized", ioe); - } - } - // A keystore entry and associated attributes private static class Entry { Date date; // the creation date of this entry @@ -1655,9 +1631,9 @@ for (KeyStore.Entry.Attribute attribute : attributes) { String attributeName = attribute.getName(); // skip friendlyName, localKeyId and trustedKeyUsage - if (CORE_ATTRIBUTES[0].equals(attributeName) || - CORE_ATTRIBUTES[1].equals(attributeName) || - CORE_ATTRIBUTES[2].equals(attributeName)) { + if (CORE_ATTRIBUTES[0].value().equals(attributeName) || + CORE_ATTRIBUTES[1].value().equals(attributeName) || + CORE_ATTRIBUTES[2].value().equals(attributeName)) { continue; } attrs.write(((PKCS12Attribute) attribute).getEncoded()); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/CertPathHelper.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -26,14 +26,10 @@ package sun.security.provider.certpath; import java.util.Date; -import java.util.Set; import java.security.cert.TrustAnchor; -import java.security.cert.X509CertSelector; import java.security.cert.X509CRLSelector; -import sun.security.x509.GeneralNameInterface; - /** * Helper class that allows access to JDK specific known-public methods in the * java.security.cert package. It relies on a subclass in the @@ -55,18 +51,10 @@ // empty } - protected abstract void implSetPathToNames(X509CertSelector sel, - Set names); - protected abstract void implSetDateAndTime(X509CRLSelector sel, Date date, long skew); protected abstract boolean implIsJdkCA(TrustAnchor anchor); - static void setPathToNames(X509CertSelector sel, - Set names) { - instance.implSetPathToNames(sel, names); - } - public static void setDateAndTime(X509CRLSelector sel, Date date, long skew) { instance.implSetDateAndTime(sel, date, skew); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java 2023-10-06 05:33:33.000000000 +0000 @@ -48,7 +48,6 @@ import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.AuthorityKeyIdentifierExtension; import static sun.security.x509.PKIXExtensions.*; -import sun.security.x509.SubjectAlternativeNameExtension; import sun.security.x509.X500Name; import sun.security.x509.X509CertImpl; @@ -259,14 +258,6 @@ caSelector.setSubject(currentState.issuerDN); /* - * Match on subjectNamesTraversed (both DNs and AltNames) - * (checks that current cert's name constraints permit it - * to certify all the DNs and AltNames that have been traversed) - */ - CertPathHelper.setPathToNames - (caSelector, currentState.subjectNamesTraversed); - - /* * check the validity period */ caSelector.setValidityPeriod(currentState.cert.getNotBefore(), @@ -704,19 +695,6 @@ // Don't bother to verify untrusted certificate more. currState.untrustedChecker.check(cert, Collections.emptySet()); - /* - * Abort if we encounter the same certificate or a certificate with - * the same public key, subject DN, and subjectAltNames as a cert - * that is already in path. - */ - for (X509Certificate cpListCert : certPathList) { - if (repeated(cpListCert, cert)) { - throw new CertPathValidatorException( - "cert with repeated subject, public key, and " + - "subjectAltNames detected"); - } - } - /* check if trusted cert */ boolean isTrustedCert = trustedCerts.contains(cert); @@ -794,49 +772,6 @@ } } - /** - * Return true if two certificates are equal or have the same subject, - * public key, and subject alternative names. - */ - private static boolean repeated( - X509Certificate currCert, X509Certificate nextCert) { - if (currCert.equals(nextCert)) { - return true; - } - return (currCert.getSubjectX500Principal().equals( - nextCert.getSubjectX500Principal()) && - currCert.getPublicKey().equals(nextCert.getPublicKey()) && - altNamesEqual(currCert, nextCert)); - } - - /** - * Return true if two certificates have the same subject alternative names. - */ - private static boolean altNamesEqual( - X509Certificate currCert, X509Certificate nextCert) { - X509CertImpl curr, next; - try { - curr = X509CertImpl.toImpl(currCert); - next = X509CertImpl.toImpl(nextCert); - } catch (CertificateException ce) { - return false; - } - - SubjectAlternativeNameExtension currAltNameExt = - curr.getSubjectAlternativeNameExtension(); - SubjectAlternativeNameExtension nextAltNameExt = - next.getSubjectAlternativeNameExtension(); - if (currAltNameExt != null) { - if (nextAltNameExt == null) { - return false; - } - return Arrays.equals(currAltNameExt.getExtensionValue(), - nextAltNameExt.getExtensionValue()); - } else { - return (nextAltNameExt == null); - } - } - /** * Verifies whether the input certificate completes the path. * First checks the cert against each trust anchor that was specified, diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/ForwardState.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,17 +31,11 @@ import java.security.cert.PKIXCertPathChecker; import java.security.cert.X509Certificate; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.ListIterator; import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; -import sun.security.x509.SubjectAlternativeNameExtension; -import sun.security.x509.GeneralNames; -import sun.security.x509.GeneralName; -import sun.security.x509.GeneralNameInterface; -import sun.security.x509.X500Name; import sun.security.x509.X509CertImpl; /** @@ -61,9 +55,6 @@ /* The last cert in the path */ X509CertImpl cert; - /* The set of subjectDNs and subjectAltNames of all certs in the path */ - HashSet subjectNamesTraversed; - /* * The number of intermediate CA certs which have been traversed so * far in the path @@ -73,7 +64,6 @@ /* Flag indicating if state is initial (path is just starting) */ private boolean init = true; - /* the untrusted certificates checker */ UntrustedChecker untrustedChecker; @@ -104,8 +94,6 @@ sb.append("\n issuerDN of last cert: ").append(issuerDN); sb.append("\n traversedCACerts: ").append(traversedCACerts); sb.append("\n init: ").append(String.valueOf(init)); - sb.append("\n subjectNamesTraversed: \n").append - (subjectNamesTraversed); sb.append("\n selfIssued: ").append (String.valueOf(selfIssued)); sb.append("]\n"); @@ -120,7 +108,6 @@ public void initState(List certPathCheckers) throws CertPathValidatorException { - subjectNamesTraversed = new HashSet(); traversedCACerts = 0; /* @@ -170,32 +157,6 @@ } } - /* update subjectNamesTraversed only if this is the EE cert or if - this cert is not self-issued */ - if (init || !selfIssued) { - X500Principal subjName = cert.getSubjectX500Principal(); - subjectNamesTraversed.add(X500Name.asX500Name(subjName)); - - try { - SubjectAlternativeNameExtension subjAltNameExt - = icert.getSubjectAlternativeNameExtension(); - if (subjAltNameExt != null) { - GeneralNames gNames = subjAltNameExt.get( - SubjectAlternativeNameExtension.SUBJECT_NAME); - for (GeneralName gName : gNames.names()) { - subjectNamesTraversed.add(gName.getName()); - } - } - } catch (IOException e) { - if (debug != null) { - debug.println("ForwardState.updateState() unexpected " - + "exception"); - e.printStackTrace(); - } - throw new CertPathValidatorException(e); - } - } - init = false; } @@ -203,10 +164,6 @@ * Clone current state. The state is cloned as each cert is * added to the path. This is necessary if backtracking occurs, * and a prior state needs to be restored. - * - * Note that this is a SMART clone. Not all fields are fully copied, - * because some of them will - * not have their contents modified by subsequent calls to updateState. */ @Override @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly @@ -226,13 +183,6 @@ } } - /* - * Shallow copy traversed names. There is no need to - * deep copy contents, since the elements of the Set - * are never modified by subsequent calls to updateState(). - */ - clonedState.subjectNamesTraversed - = (HashSet)subjectNamesTraversed.clone(); return clonedState; } catch (CloneNotSupportedException e) { throw new InternalError(e.toString(), e); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java 2023-10-06 05:33:33.000000000 +0000 @@ -135,7 +135,7 @@ private static final Debug debug = Debug.getInstance("certpath"); private static final boolean dump = debug != null && Debug.isOn("ocsp"); private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID = - ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 1}); + ObjectIdentifier.of(KnownOIDs.OCSPBasicResponse); private static final int CERT_STATUS_GOOD = 0; private static final int CERT_STATUS_REVOKED = 1; private static final int CERT_STATUS_UNKNOWN = 2; @@ -144,9 +144,6 @@ private static final int NAME_TAG = 1; private static final int KEY_TAG = 2; - // Object identifier for the OCSPSigning key purpose - private static final String KP_OCSP_SIGNING_OID = "1.3.6.1.5.5.7.3.9"; - // Default maximum clock skew in milliseconds (15 minutes) // allowed when checking validity of OCSP responses private static final int DEFAULT_MAX_CLOCK_SKEW = 900000; @@ -357,7 +354,7 @@ try { for (int i = 0; i < derCerts.length; i++) { X509CertImpl cert = - new X509CertImpl(derCerts[i].toByteArray()); + X509CertImpl.newX509CertImpl(derCerts[i].toByteArray()); certs.add(cert); if (debug != null) { @@ -495,7 +492,7 @@ try { List keyPurposes = signerCert.getExtendedKeyUsage(); if (keyPurposes == null || - !keyPurposes.contains(KP_OCSP_SIGNING_OID)) { + !keyPurposes.contains(KnownOIDs.OCSPSigning.value())) { throw new CertPathValidatorException( "Responder's certificate not valid for signing " + "OCSP responses"); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java 2023-10-06 05:33:33.000000000 +0000 @@ -228,13 +228,13 @@ X509ValidationEvent xve = new X509ValidationEvent(); if (xve.shouldCommit() || EventHelper.isLoggingSecurity()) { int[] certIds = params.certificates().stream() - .mapToInt(x -> x.hashCode()) + .mapToInt(Certificate::hashCode) .toArray(); - int anchorCertId = - anchor.getTrustedCert().hashCode(); + int anchorCertId = (anchorCert != null) ? + anchorCert.hashCode() : anchor.getCAPublicKey().hashCode(); if (xve.shouldCommit()) { xve.certificateId = anchorCertId; - int certificatePos = 1; //anchor cert + int certificatePos = 1; // most trusted CA xve.certificatePosition = certificatePos; xve.validationCounter = validationCounter.incrementAndGet(); xve.commit(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java 2023-10-06 05:33:33.000000000 +0000 @@ -46,6 +46,7 @@ import sun.security.x509.*; import static sun.security.x509.PKIXExtensions.*; import sun.security.util.Debug; +import sun.security.util.KnownOIDs; class RevocationChecker extends PKIXRevocationChecker { @@ -723,7 +724,7 @@ // verify the response byte[] nonce = null; for (Extension ext : ocspExtensions) { - if (ext.getId().equals("1.3.6.1.5.5.7.48.1.2")) { + if (ext.getId().equals(KnownOIDs.OCSPNonceExt.value())) { nonce = ext.getValue(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java 2023-10-06 05:33:33.000000000 +0000 @@ -33,6 +33,7 @@ import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.PKIXReason; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -42,6 +43,7 @@ import sun.security.provider.certpath.PKIX.BuilderParams; import static sun.security.x509.PKIXExtensions.*; +import sun.security.x509.SubjectAlternativeNameExtension; import sun.security.x509.X509CertImpl; import sun.security.util.Debug; @@ -265,7 +267,7 @@ */ Collection certs = builder.getMatchingCerts(currentState, buildParams.certStores()); - List vertices = addVertices(certs, adjList); + List vertices = addVertices(certs, adjList, cpList); if (debug != null) { debug.println("SunCertPathBuilder.depthFirstSearchForward(): " + "certs.size=" + vertices.size()); @@ -325,17 +327,32 @@ * cert (which is signed by the trusted public key), but * don't add it yet to the cpList */ + PublicKey rootKey = cert.getPublicKey(); if (builder.trustAnchor.getTrustedCert() == null) { appendedCerts.add(0, cert); + rootKey = builder.trustAnchor.getCAPublicKey(); + if (debug != null) + debug.println( + "SunCertPathBuilder.depthFirstSearchForward " + + "using buildParams public key: " + + rootKey.toString()); } + TrustAnchor anchor = new TrustAnchor + (cert.getSubjectX500Principal(), rootKey, null); + // add the basic checker + List checkers = new ArrayList<>(); + BasicChecker basicChecker = new BasicChecker(anchor, + buildParams.date(), + buildParams.sigProvider(), + true); + checkers.add(basicChecker); Set initExpPolSet = Collections.singleton(PolicyChecker.ANY_POLICY); PolicyNodeImpl rootNode = new PolicyNodeImpl(null, PolicyChecker.ANY_POLICY, null, false, initExpPolSet, false); - List checkers = new ArrayList<>(); PolicyChecker policyChecker = new PolicyChecker(buildParams.initialPolicies(), appendedCerts.size(), @@ -346,28 +363,13 @@ rootNode); checkers.add(policyChecker); + // add the constraints checker + checkers.add(new ConstraintsChecker(appendedCerts.size())); + // add the algorithm checker checkers.add(new AlgorithmChecker(builder.trustAnchor, buildParams.timestamp(), buildParams.variant())); - PublicKey rootKey = cert.getPublicKey(); - if (builder.trustAnchor.getTrustedCert() == null) { - rootKey = builder.trustAnchor.getCAPublicKey(); - if (debug != null) - debug.println( - "SunCertPathBuilder.depthFirstSearchForward " + - "using buildParams public key: " + - rootKey.toString()); - } - TrustAnchor anchor = new TrustAnchor - (cert.getSubjectX500Principal(), rootKey, null); - - // add the basic checker - BasicChecker basicChecker = new BasicChecker(anchor, - buildParams.date(), - buildParams.sigProvider(), - true); - checkers.add(basicChecker); buildParams.setCertPath(cf.generateCertPath(appendedCerts)); @@ -563,19 +565,80 @@ * adjacency list. */ private static List addVertices(Collection certs, - List> adjList) + List> adjList, + List cpList) { List l = adjList.get(adjList.size() - 1); for (X509Certificate cert : certs) { - Vertex v = new Vertex(cert); - l.add(v); + boolean repeated = false; + for (X509Certificate cpListCert : cpList) { + /* + * Ignore if we encounter the same certificate or a + * certificate with the same public key, subject DN, and + * subjectAltNames as a cert that is already in path. + */ + if (repeated(cpListCert, cert)) { + if (debug != null) { + debug.println("cert with repeated subject, " + + "public key, and subjectAltNames detected"); + } + repeated = true; + break; + } + } + if (!repeated) { + l.add(new Vertex(cert)); + } } return l; } /** + * Return true if two certificates are equal or have the same subject, + * public key, and subject alternative names. + */ + private static boolean repeated( + X509Certificate currCert, X509Certificate nextCert) { + if (currCert.equals(nextCert)) { + return true; + } + return (currCert.getSubjectX500Principal().equals( + nextCert.getSubjectX500Principal()) && + currCert.getPublicKey().equals(nextCert.getPublicKey()) && + altNamesEqual(currCert, nextCert)); + } + + /** + * Return true if two certificates have the same subject alternative names. + */ + private static boolean altNamesEqual( + X509Certificate currCert, X509Certificate nextCert) { + X509CertImpl curr, next; + try { + curr = X509CertImpl.toImpl(currCert); + next = X509CertImpl.toImpl(nextCert); + } catch (CertificateException ce) { + return false; + } + + SubjectAlternativeNameExtension currAltNameExt = + curr.getSubjectAlternativeNameExtension(); + SubjectAlternativeNameExtension nextAltNameExt = + next.getSubjectAlternativeNameExtension(); + if (currAltNameExt != null) { + if (nextAltNameExt == null) { + return false; + } + return Arrays.equals(currAltNameExt.getExtensionValue(), + nextAltNameExt.getExtensionValue()); + } else { + return (nextAltNameExt == null); + } + } + + /** * Returns true if trust anchor certificate matches specified * certificate constraints. */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/X509CertificatePair.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/X509CertificatePair.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/X509CertificatePair.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/X509CertificatePair.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -240,7 +240,7 @@ } opt = opt.data.getDerValue(); forward = X509Factory.intern - (new X509CertImpl(opt.toByteArray())); + (X509CertImpl.newX509CertImpl(opt.toByteArray())); } break; case TAG_REVERSE: @@ -251,7 +251,7 @@ } opt = opt.data.getDerValue(); reverse = X509Factory.intern - (new X509CertImpl(opt.toByteArray())); + (X509CertImpl.newX509CertImpl(opt.toByteArray())); } break; default: diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, 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 @@ -25,10 +25,7 @@ package sun.security.provider.certpath; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.security.cert.CertificateEncodingException; import java.security.cert.Certificate; import java.security.cert.CertificateException; @@ -394,4 +391,19 @@ public List getCertificates() { return certs; } + + /** + * Restores the state of this object from the stream. + *

+ * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "X509CertPaths are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/DSAPublicKeyImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/DSAPublicKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/DSAPublicKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/DSAPublicKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -25,17 +25,20 @@ package sun.security.provider; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.KeyRep; import java.security.InvalidKeyException; /** * An X.509 public key for the Digital Signature Algorithm. - * + *

* The difference between DSAPublicKeyImpl and DSAPublicKey is that * DSAPublicKeyImpl calls writeReplace with KeyRep, and DSAPublicKey * calls writeObject. - * + *

* See the comments in DSAKeyFactory, 4532506, and 6232513. * */ @@ -70,10 +73,25 @@ super(encoded); } - protected Object writeReplace() throws java.io.ObjectStreamException { + private Object writeReplace() throws java.io.ObjectStreamException { return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded()); } + + /** + * Restores the state of this object from the stream. + *

+ * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "DSAPublicKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/KeyProtector.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/KeyProtector.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/KeyProtector.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/KeyProtector.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -39,6 +39,7 @@ import sun.security.pkcs.EncryptedPrivateKeyInfo; import sun.security.x509.AlgorithmId; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.util.DerValue; /** @@ -106,9 +107,6 @@ private static final String DIGEST_ALG = "SHA"; private static final int DIGEST_LEN = 20; - // defined by JavaSoft - private static final String KEY_PROTECTOR_OID = "1.3.6.1.4.1.42.2.17.1.1"; - // The password used for protecting/recovering keys passed through this // key protector. We store it as a byte array, so that we can digest it. private byte[] passwdBytes; @@ -214,7 +212,8 @@ // EncryptedPrivateKeyInfo, and returns its encoding AlgorithmId encrAlg; try { - encrAlg = new AlgorithmId(new ObjectIdentifier(KEY_PROTECTOR_OID)); + encrAlg = new AlgorithmId(ObjectIdentifier.of + (KnownOIDs.JAVASOFT_JDKKeyProtector)); return new EncryptedPrivateKeyInfo(encrAlg,encrKey).getEncoded(); } catch (IOException ioe) { throw new KeyStoreException(ioe.getMessage()); @@ -236,7 +235,8 @@ // do we support the algorithm? AlgorithmId encrAlg = encrInfo.getAlgorithm(); - if (!(encrAlg.getOID().toString().equals(KEY_PROTECTOR_OID))) { + if (!(encrAlg.getOID().toString().equals + (KnownOIDs.JAVASOFT_JDKKeyProtector.value()))) { throw new UnrecoverableKeyException("Unsupported key protection " + "algorithm"); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/PolicyFile.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/PolicyFile.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/PolicyFile.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/PolicyFile.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, 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 @@ -2090,8 +2090,17 @@ this.actions.equals(that.actions))) return false; - if (this.certs.length != that.certs.length) + if ((this.certs == null) && (that.certs == null)) { + return true; + } + + if ((this.certs == null) || (that.certs == null)) { + return false; + } + + if (this.certs.length != that.certs.length) { return false; + } int i,j; boolean match; @@ -2161,7 +2170,7 @@ } public Certificate[] getCerts() { - return certs; + return (certs == null ? null : certs.clone()); } /** @@ -2174,6 +2183,21 @@ @Override public String toString() { return "(SelfPermission " + type + " " + name + " " + actions + ")"; } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (certs != null) { + this.certs = certs.clone(); + } + } } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/SecureRandom.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/SecureRandom.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/SecureRandom.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/SecureRandom.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. * 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 sun.security.provider; import java.io.IOException; +import java.io.InvalidObjectException; import java.security.MessageDigest; import java.security.SecureRandomSpi; import java.security.NoSuchAlgorithmException; @@ -187,7 +188,7 @@ /** * This static object will be seeded by SeedGenerator, and used * to seed future instances of SHA1PRNG SecureRandoms. - * + *

* Bloch, Effective Java Second Edition: Item 71 */ private static class SeederHolder { @@ -262,17 +263,23 @@ } /* - * readObject is called to restore the state of the random object from - * a stream. We have to create a new instance of MessageDigest, because + * This method is called to restore the state of the random object from + * a stream. + *

+ * We have to create a new instance of {@code MessageDigest}, because * it is not included in the stream (it is marked "transient"). - * - * Note that the engineNextBytes() method invoked on the restored random - * object will yield the exact same (random) bytes as the original. + *

+ * Note that the {@code engineNextBytes()} method invoked on the restored + * random object will yield the exact same (random) bytes as the original. * If you do not want this behaviour, you should re-seed the restored - * random object, using engineSetSeed(). + * random object, using {@code engineSetSeed()}. + * + * @param s the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded */ private void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException { + throws IOException, ClassNotFoundException { s.defaultReadObject (); @@ -291,5 +298,34 @@ "internal error: SHA-1 not available.", exc); } } + + // Various consistency checks + if ((remainder == null) && (remCount > 0)) { + throw new InvalidObjectException( + "Remainder indicated, but no data available"); + } + + // Not yet allocated state + if (state == null) { + if (remainder == null) { + return; + } else { + throw new InvalidObjectException( + "Inconsistent buffer allocations"); + } + } + + // Sanity check on sizes/pointer + if ((state.length != DIGEST_SIZE) || + ((remainder != null) && (remainder.length != DIGEST_SIZE)) || + (remCount < 0 ) || (remCount >= DIGEST_SIZE)) { + throw new InvalidObjectException( + "Inconsistent buffer sizes/state"); + } + + state = state.clone(); + if (remainder != null) { + remainder = remainder.clone(); + } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/SunEntries.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/SunEntries.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/SunEntries.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/SunEntries.java 2023-10-06 05:33:33.000000000 +0000 @@ -32,6 +32,8 @@ import jdk.internal.util.StaticProperty; import sun.security.action.GetPropertyAction; +import sun.security.util.SecurityProviderConstants; +import static sun.security.util.SecurityProviderConstants.getAliases; /** * Defines the entries of the SUN provider. @@ -80,18 +82,6 @@ // the default algo used by SecureRandom class for new SecureRandom() calls public static final String DEF_SECURE_RANDOM_ALGO; - // create an aliases List from the specified aliases - public static List createAliases(String ... aliases) { - return Arrays.asList(aliases); - } - - // create an aliases List from the specified oid followed by other aliases - public static List createAliasesWithOid(String ... oids) { - String[] result = Arrays.copyOf(oids, oids.length + 1); - result[result.length - 1] = "OID." + oids[0]; - return Arrays.asList(result); - } - SunEntries(Provider p) { services = new LinkedHashSet<>(50, 0.9f); @@ -106,22 +96,20 @@ attrs.put("ThreadSafe", "true"); if (NativePRNG.isAvailable()) { add(p, "SecureRandom", "NativePRNG", - "sun.security.provider.NativePRNG", - null, attrs); + "sun.security.provider.NativePRNG", attrs); } if (NativePRNG.Blocking.isAvailable()) { add(p, "SecureRandom", "NativePRNGBlocking", - "sun.security.provider.NativePRNG$Blocking", null, attrs); + "sun.security.provider.NativePRNG$Blocking", attrs); } if (NativePRNG.NonBlocking.isAvailable()) { add(p, "SecureRandom", "NativePRNGNonBlocking", - "sun.security.provider.NativePRNG$NonBlocking", null, attrs); + "sun.security.provider.NativePRNG$NonBlocking", attrs); } attrs.put("ImplementedIn", "Software"); - add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", - null, attrs); + add(p, "SecureRandom", "DRBG", "sun.security.provider.DRBG", attrs); add(p, "SecureRandom", "SHA1PRNG", - "sun.security.provider.SecureRandom", null, attrs); + "sun.security.provider.SecureRandom", attrs); /* * Signature engines @@ -134,37 +122,28 @@ attrs.put("KeySize", "1024"); // for NONE and SHA1 DSA signatures - add(p, "Signature", "SHA1withDSA", - "sun.security.provider.DSA$SHA1withDSA", - createAliasesWithOid("1.2.840.10040.4.3", "DSA", "DSS", - "SHA/DSA", "SHA-1/DSA", "SHA1/DSA", "SHAwithDSA", - "DSAWithSHA1", "1.3.14.3.2.13", "1.3.14.3.2.27"), attrs); - add(p, "Signature", "NONEwithDSA", "sun.security.provider.DSA$RawDSA", - createAliases("RawDSA"), attrs); + addWithAlias(p, "Signature", "SHA1withDSA", + "sun.security.provider.DSA$SHA1withDSA", attrs); + addWithAlias(p, "Signature", "NONEwithDSA", + "sun.security.provider.DSA$RawDSA", attrs); attrs.put("KeySize", "2048"); // for SHA224 and SHA256 DSA signatures - add(p, "Signature", "SHA224withDSA", - "sun.security.provider.DSA$SHA224withDSA", - createAliasesWithOid("2.16.840.1.101.3.4.3.1"), attrs); - add(p, "Signature", "SHA256withDSA", - "sun.security.provider.DSA$SHA256withDSA", - createAliasesWithOid("2.16.840.1.101.3.4.3.2"), attrs); + addWithAlias(p, "Signature", "SHA224withDSA", + "sun.security.provider.DSA$SHA224withDSA", attrs); + addWithAlias(p, "Signature", "SHA256withDSA", + "sun.security.provider.DSA$SHA256withDSA", attrs); attrs.remove("KeySize"); add(p, "Signature", "SHA1withDSAinP1363Format", - "sun.security.provider.DSA$SHA1withDSAinP1363Format", - null, null); + "sun.security.provider.DSA$SHA1withDSAinP1363Format"); add(p, "Signature", "NONEwithDSAinP1363Format", - "sun.security.provider.DSA$RawDSAinP1363Format", - null, null); + "sun.security.provider.DSA$RawDSAinP1363Format"); add(p, "Signature", "SHA224withDSAinP1363Format", - "sun.security.provider.DSA$SHA224withDSAinP1363Format", - null, null); + "sun.security.provider.DSA$SHA224withDSAinP1363Format"); add(p, "Signature", "SHA256withDSAinP1363Format", - "sun.security.provider.DSA$SHA256withDSAinP1363Format", - null, null); + "sun.security.provider.DSA$SHA256withDSAinP1363Format"); /* * Key Pair Generator engines @@ -173,85 +152,75 @@ attrs.put("ImplementedIn", "Software"); attrs.put("KeySize", "2048"); // for DSA KPG and APG only - String dsaOid = "1.2.840.10040.4.1"; - List dsaAliases = createAliasesWithOid(dsaOid, "1.3.14.3.2.12"); String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$"; dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current"); - add(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, dsaAliases, attrs); + addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs); /* * Algorithm Parameter Generator engines */ - add(p, "AlgorithmParameterGenerator", "DSA", - "sun.security.provider.DSAParameterGenerator", dsaAliases, - attrs); + addWithAlias(p, "AlgorithmParameterGenerator", "DSA", + "sun.security.provider.DSAParameterGenerator", attrs); attrs.remove("KeySize"); /* * Algorithm Parameter engines */ - add(p, "AlgorithmParameters", "DSA", - "sun.security.provider.DSAParameters", dsaAliases, attrs); + addWithAlias(p, "AlgorithmParameters", "DSA", + "sun.security.provider.DSAParameters", attrs); /* * Key factories */ - add(p, "KeyFactory", "DSA", "sun.security.provider.DSAKeyFactory", - dsaAliases, attrs); + addWithAlias(p, "KeyFactory", "DSA", + "sun.security.provider.DSAKeyFactory", attrs); /* * Digest engines */ - add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", null, attrs); - add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", null, attrs); - add(p, "MessageDigest", "SHA", "sun.security.provider.SHA", - createAliasesWithOid("1.3.14.3.2.26", "SHA-1", "SHA1"), attrs); - - String sha2BaseOid = "2.16.840.1.101.3.4.2"; - add(p, "MessageDigest", "SHA-224", "sun.security.provider.SHA2$SHA224", - createAliasesWithOid(sha2BaseOid + ".4"), attrs); - add(p, "MessageDigest", "SHA-256", "sun.security.provider.SHA2$SHA256", - createAliasesWithOid(sha2BaseOid + ".1"), attrs); - add(p, "MessageDigest", "SHA-384", "sun.security.provider.SHA5$SHA384", - createAliasesWithOid(sha2BaseOid + ".2"), attrs); - add(p, "MessageDigest", "SHA-512", "sun.security.provider.SHA5$SHA512", - createAliasesWithOid(sha2BaseOid + ".3"), attrs); - add(p, "MessageDigest", "SHA-512/224", - "sun.security.provider.SHA5$SHA512_224", - createAliasesWithOid(sha2BaseOid + ".5"), attrs); - add(p, "MessageDigest", "SHA-512/256", - "sun.security.provider.SHA5$SHA512_256", - createAliasesWithOid(sha2BaseOid + ".6"), attrs); - add(p, "MessageDigest", "SHA3-224", "sun.security.provider.SHA3$SHA224", - createAliasesWithOid(sha2BaseOid + ".7"), attrs); - add(p, "MessageDigest", "SHA3-256", "sun.security.provider.SHA3$SHA256", - createAliasesWithOid(sha2BaseOid + ".8"), attrs); - add(p, "MessageDigest", "SHA3-384", "sun.security.provider.SHA3$SHA384", - createAliasesWithOid(sha2BaseOid + ".9"), attrs); - add(p, "MessageDigest", "SHA3-512", "sun.security.provider.SHA3$SHA512", - createAliasesWithOid(sha2BaseOid + ".10"), attrs); + add(p, "MessageDigest", "MD2", "sun.security.provider.MD2", attrs); + add(p, "MessageDigest", "MD5", "sun.security.provider.MD5", attrs); + addWithAlias(p, "MessageDigest", "SHA-1", "sun.security.provider.SHA", + attrs); + + addWithAlias(p, "MessageDigest", "SHA-224", + "sun.security.provider.SHA2$SHA224", attrs); + addWithAlias(p, "MessageDigest", "SHA-256", + "sun.security.provider.SHA2$SHA256", attrs); + addWithAlias(p, "MessageDigest", "SHA-384", + "sun.security.provider.SHA5$SHA384", attrs); + addWithAlias(p, "MessageDigest", "SHA-512", + "sun.security.provider.SHA5$SHA512", attrs); + addWithAlias(p, "MessageDigest", "SHA-512/224", + "sun.security.provider.SHA5$SHA512_224", attrs); + addWithAlias(p, "MessageDigest", "SHA-512/256", + "sun.security.provider.SHA5$SHA512_256", attrs); + addWithAlias(p, "MessageDigest", "SHA3-224", + "sun.security.provider.SHA3$SHA224", attrs); + addWithAlias(p, "MessageDigest", "SHA3-256", + "sun.security.provider.SHA3$SHA256", attrs); + addWithAlias(p, "MessageDigest", "SHA3-384", + "sun.security.provider.SHA3$SHA384", attrs); + addWithAlias(p, "MessageDigest", "SHA3-512", + "sun.security.provider.SHA3$SHA512", attrs); /* * Certificates */ - add(p, "CertificateFactory", "X.509", - "sun.security.provider.X509Factory", - createAliases("X509"), attrs); + addWithAlias(p, "CertificateFactory", "X.509", + "sun.security.provider.X509Factory", attrs); /* * KeyStore */ add(p, "KeyStore", "PKCS12", - "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", - null, null); + "sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12"); add(p, "KeyStore", "JKS", - "sun.security.provider.JavaKeyStore$DualFormatJKS", - null, attrs); + "sun.security.provider.JavaKeyStore$DualFormatJKS", attrs); add(p, "KeyStore", "CaseExactJKS", - "sun.security.provider.JavaKeyStore$CaseExactJKS", - null, attrs); + "sun.security.provider.JavaKeyStore$CaseExactJKS", attrs); add(p, "KeyStore", "DKS", "sun.security.provider.DomainKeyStore$DKS", - null, attrs); + attrs); /* @@ -259,22 +228,21 @@ */ add(p, "CertStore", "Collection", "sun.security.provider.certpath.CollectionCertStore", - null, attrs); + attrs); add(p, "CertStore", "com.sun.security.IndexedCollection", "sun.security.provider.certpath.IndexedCollectionCertStore", - null, attrs); + attrs); /* * Policy */ - add(p, "Policy", "JavaPolicy", "sun.security.provider.PolicySpiFile", - null, null); + add(p, "Policy", "JavaPolicy", "sun.security.provider.PolicySpiFile"); /* * Configuration */ add(p, "Configuration", "JavaLoginConfig", - "sun.security.provider.ConfigFile$Spi", null, null); + "sun.security.provider.ConfigFile$Spi"); /* * CertPathBuilder and CertPathValidator @@ -285,19 +253,29 @@ add(p, "CertPathBuilder", "PKIX", "sun.security.provider.certpath.SunCertPathBuilder", - null, attrs); + attrs); add(p, "CertPathValidator", "PKIX", "sun.security.provider.certpath.PKIXCertPathValidator", - null, attrs); + attrs); } Iterator iterator() { return services.iterator(); } + private void add(Provider p, String type, String algo, String cn) { + services.add(new Provider.Service(p, type, algo, cn, null, null)); + } + private void add(Provider p, String type, String algo, String cn, - List aliases, HashMap attrs) { - services.add(new Provider.Service(p, type, algo, cn, aliases, attrs)); + HashMap attrs) { + services.add(new Provider.Service(p, type, algo, cn, null, attrs)); + } + + private void addWithAlias(Provider p, String type, String algo, String cn, + HashMap attrs) { + services.add(new Provider.Service(p, type, algo, cn, + getAliases(algo), attrs)); } private LinkedHashSet services; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/X509Factory.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/X509Factory.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/provider/X509Factory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/provider/X509Factory.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,12 +26,9 @@ package sun.security.provider; import java.io.*; -import java.security.PublicKey; import java.util.*; import java.security.cert.*; -import jdk.internal.event.EventHelper; -import jdk.internal.event.X509CertificateEvent; import sun.security.util.KeyUtil; import sun.security.util.Pem; import sun.security.x509.*; @@ -104,8 +101,6 @@ } cert = new X509CertImpl(encoding); addToCache(certCache, cert.getEncodedInternal(), cert); - // record cert details if necessary - commitEvent(cert); return cert; } else { throw new IOException("Empty input"); @@ -473,7 +468,7 @@ } } catch (ParsingException e) { while (data != null) { - coll.add(new X509CertImpl(data)); + coll.add(X509CertImpl.newX509CertImpl(data)); data = readOneBlock(pbis); } } @@ -766,43 +761,4 @@ } return tag; } - - private void commitEvent(X509CertImpl info) { - X509CertificateEvent xce = new X509CertificateEvent(); - if (xce.shouldCommit() || EventHelper.isLoggingSecurity()) { - PublicKey pKey = info.getPublicKey(); - String algId = info.getSigAlgName(); - String serNum = info.getSerialNumber().toString(16); - String subject = info.getSubjectDN().getName(); - String issuer = info.getIssuerDN().getName(); - String keyType = pKey.getAlgorithm(); - int length = KeyUtil.getKeySize(pKey); - int hashCode = info.hashCode(); - long beginDate = info.getNotBefore().getTime(); - long endDate = info.getNotAfter().getTime(); - if (xce.shouldCommit()) { - xce.algorithm = algId; - xce.serialNumber = serNum; - xce.subject = subject; - xce.issuer = issuer; - xce.keyType = keyType; - xce.keyLength = length; - xce.certificateId = hashCode; - xce.validFrom = beginDate; - xce.validUntil = endDate; - xce.commit(); - } - if (EventHelper.isLoggingSecurity()) { - EventHelper.logX509CertificateEvent(algId, - serNum, - subject, - issuer, - keyType, - length, - hashCode, - beginDate, - endDate); - } - } - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/PSSParameters.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/PSSParameters.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/PSSParameters.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/PSSParameters.java 2023-10-06 05:33:33.000000000 +0000 @@ -99,7 +99,7 @@ } else if (d.isContextSpecific((byte) 0x01)) { // mgf algid AlgorithmId val = AlgorithmId.parse(d.data.getDerValue()); - if (!val.getOID().equals(AlgorithmId.mgf1_oid)) { + if (!val.getOID().equals(AlgorithmId.MGF1_oid)) { throw new IOException("Only MGF1 mgf is supported"); } @@ -247,7 +247,7 @@ if (!mgfDigestId.getOID().equals(AlgorithmId.SHA_oid)) { tmp2 = new DerOutputStream(); - tmp2.putOID(AlgorithmId.mgf1_oid); + tmp2.putOID(AlgorithmId.MGF1_oid); mgfDigestId.encode(tmp2); tmp3 = new DerOutputStream(); tmp3.write(DerValue.tag_Sequence, tmp2); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAKeyFactory.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -32,8 +32,7 @@ import java.security.spec.*; import sun.security.action.GetPropertyAction; -import sun.security.x509.AlgorithmId; -import static sun.security.rsa.RSAUtil.KeyType; +import sun.security.rsa.RSAUtil.KeyType; /** * KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS". @@ -44,13 +43,15 @@ * between the following: * * For public keys: - * . PublicKey with an X.509 encoding + * . RSA PublicKey with an X.509 encoding + * . RSA PublicKey with an PKCS#1 encoding * . RSAPublicKey * . RSAPublicKeySpec * . X509EncodedKeySpec * * For private keys: - * . PrivateKey with a PKCS#8 encoding + * . RSA PrivateKey with a PKCS#8 encoding + * . RSA PrivateKey with a PKCS#1 encoding * . RSAPrivateKey * . RSAPrivateCrtKey * . RSAPrivateKeySpec @@ -96,8 +97,8 @@ return new RSAKeyFactory(type); } - // Internal utility method for checking key algorithm - private static void checkKeyAlgo(Key key, String expectedAlg) + // pkg-private utility method for checking key algorithm + static void checkKeyAlgo(Key key, String expectedAlg) throws InvalidKeyException { String keyAlg = key.getAlgorithm(); if (keyAlg == null || !(keyAlg.equalsIgnoreCase(expectedAlg))) { @@ -211,7 +212,7 @@ throw new InvalidKeyException("Key must not be null"); } // ensure the key algorithm matches the current KeyFactory instance - checkKeyAlgo(key, type.keyAlgo()); + checkKeyAlgo(key, type.keyAlgo); // no translation needed if the key is already our own impl if ((key instanceof RSAPrivateKeyImpl) || @@ -259,21 +260,17 @@ RSAPublicKey rsaKey = (RSAPublicKey)key; try { return new RSAPublicKeyImpl( - RSAUtil.createAlgorithmId(type, rsaKey.getParams()), + type, rsaKey.getParams(), rsaKey.getModulus(), rsaKey.getPublicExponent()); } catch (ProviderException e) { // catch providers that incorrectly implement RSAPublicKey throw new InvalidKeyException("Invalid key", e); } - } else if ("X.509".equals(key.getFormat())) { - RSAPublicKey translated = new RSAPublicKeyImpl(key.getEncoded()); - // ensure the key algorithm matches the current KeyFactory instance - checkKeyAlgo(translated, type.keyAlgo()); - return translated; } else { - throw new InvalidKeyException("Public keys must be instance " - + "of RSAPublicKey or have X.509 encoding"); + // create new key based on the format and encoding of current 'key' + return RSAPublicKeyImpl.newKey(type, key.getFormat(), + key.getEncoded()); } } @@ -284,7 +281,7 @@ RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; try { return new RSAPrivateCrtKeyImpl( - RSAUtil.createAlgorithmId(type, rsaKey.getParams()), + type, rsaKey.getParams(), rsaKey.getModulus(), rsaKey.getPublicExponent(), rsaKey.getPrivateExponent(), @@ -302,7 +299,7 @@ RSAPrivateKey rsaKey = (RSAPrivateKey)key; try { return new RSAPrivateKeyImpl( - RSAUtil.createAlgorithmId(type, rsaKey.getParams()), + type, rsaKey.getParams(), rsaKey.getModulus(), rsaKey.getPrivateExponent() ); @@ -310,15 +307,9 @@ // catch providers that incorrectly implement RSAPrivateKey throw new InvalidKeyException("Invalid key", e); } - } else if ("PKCS#8".equals(key.getFormat())) { - RSAPrivateKey translated = - RSAPrivateCrtKeyImpl.newKey(key.getEncoded()); - // ensure the key algorithm matches the current KeyFactory instance - checkKeyAlgo(translated, type.keyAlgo()); - return translated; } else { - throw new InvalidKeyException("Private keys must be instance " - + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); + return RSAPrivateCrtKeyImpl.newKey(type, key.getFormat(), + key.getEncoded()); } } @@ -326,16 +317,13 @@ private PublicKey generatePublic(KeySpec keySpec) throws GeneralSecurityException { if (keySpec instanceof X509EncodedKeySpec) { - X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; - RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded()); - // ensure the key algorithm matches the current KeyFactory instance - checkKeyAlgo(generated, type.keyAlgo()); - return generated; + return RSAPublicKeyImpl.newKey(type, "X.509", + ((X509EncodedKeySpec)keySpec).getEncoded()); } else if (keySpec instanceof RSAPublicKeySpec) { RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; try { return new RSAPublicKeyImpl( - RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), + type, rsaSpec.getParams(), rsaSpec.getModulus(), rsaSpec.getPublicExponent() ); @@ -352,16 +340,13 @@ private PrivateKey generatePrivate(KeySpec keySpec) throws GeneralSecurityException { if (keySpec instanceof PKCS8EncodedKeySpec) { - PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; - RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); - // ensure the key algorithm matches the current KeyFactory instance - checkKeyAlgo(generated, type.keyAlgo()); - return generated; + return RSAPrivateCrtKeyImpl.newKey(type, "PKCS#8", + ((PKCS8EncodedKeySpec)keySpec).getEncoded()); } else if (keySpec instanceof RSAPrivateCrtKeySpec) { RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; try { return new RSAPrivateCrtKeyImpl( - RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), + type, rsaSpec.getParams(), rsaSpec.getModulus(), rsaSpec.getPublicExponent(), rsaSpec.getPrivateExponent(), @@ -378,7 +363,7 @@ RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; try { return new RSAPrivateKeyImpl( - RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), + type, rsaSpec.getParams(), rsaSpec.getModulus(), rsaSpec.getPrivateExponent() ); @@ -396,7 +381,8 @@ try { // convert key to one of our keys // this also verifies that the key is a valid RSA key and ensures - // that the encoding is X.509/PKCS#8 for public/private keys + // that the encoding is X.509/PKCS#8 or PKCS#1 for public/private + // keys key = engineTranslateKey(key); } catch (InvalidKeyException e) { throw new InvalidKeySpecException(e); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAKeyPairGenerator.java 2023-10-06 05:33:33.000000000 +0000 @@ -32,10 +32,10 @@ import java.security.spec.RSAKeyGenParameterSpec; import sun.security.jca.JCAUtil; +import sun.security.rsa.RSAUtil.KeyType; + import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE; import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE; -import sun.security.x509.AlgorithmId; -import static sun.security.rsa.RSAUtil.KeyType; /** * RSA keypair generation. Standard algorithm, minimum key length 512 bit. @@ -55,7 +55,7 @@ private int keySize; private final KeyType type; - private AlgorithmId rsaId; + private AlgorithmParameterSpec keyParams; // PRNG to use private SecureRandom random; @@ -116,7 +116,7 @@ } try { - this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams); + this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams); } catch (ProviderException e) { throw new InvalidAlgorithmParameterException( "Invalid key parameters", e); @@ -177,9 +177,10 @@ BigInteger coeff = q.modInverse(p); try { - PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e); - PrivateKey privateKey = new RSAPrivateCrtKeyImpl( - rsaId, n, e, d, p, q, pe, qe, coeff); + PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams, + n, e); + PrivateKey privateKey = new RSAPrivateCrtKeyImpl(type, + keyParams, n, e, d, p, q, pe, qe, coeff); return new KeyPair(publicKey, privateKey); } catch (InvalidKeyException exc) { // invalid key exception only thrown for keys < 512 bit, diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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 @@ -26,6 +26,8 @@ package sun.security.rsa; import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.*; @@ -34,16 +36,15 @@ import sun.security.util.*; -import sun.security.x509.AlgorithmId; import sun.security.pkcs.PKCS8Key; -import static sun.security.rsa.RSAUtil.KeyType; +import sun.security.rsa.RSAUtil.KeyType; /** * RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in CRT form. * For non-CRT private keys, see RSAPrivateKeyImpl. We need separate classes * to ensure correct behavior in instanceof checks, etc. - * + *

* Note: RSA keys must be at least 512 bits long * * @see RSAPrivateKeyImpl @@ -66,27 +67,52 @@ private BigInteger qe; // prime exponent q private BigInteger coeff; // CRT coeffcient + private transient KeyType type; + // Optional parameters associated with this RSA key // specified in the encoding of its AlgorithmId. // Must be null for "RSA" keys. - private AlgorithmParameterSpec keyParams; + private transient AlgorithmParameterSpec keyParams; /** - * Generate a new key from its encoding. Returns a CRT key if possible - * and a non-CRT key otherwise. Used by RSAKeyFactory. + * Generate a new RSAPrivate(Crt)Key from the specified type, + * format and encoding. Returns a CRT key if possible and a non-CRT + * key otherwise. + * Also used by SunPKCS11 provider. */ - public static RSAPrivateKey newKey(byte[] encoded) - throws InvalidKeyException { - RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded); - // check all CRT-specific components are available, if any one - // missing, return a non-CRT key instead - if (checkComponents(key)) { - return key; - } else { - return new RSAPrivateKeyImpl( - key.algid, - key.getModulus(), - key.getPrivateExponent()); + public static RSAPrivateKey newKey(KeyType type, String format, + byte[] encoded) throws InvalidKeyException { + switch (format) { + case "PKCS#8": + RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded); + RSAKeyFactory.checkKeyAlgo(key, type.keyAlgo); + // check all CRT-specific components are available, if any one + // missing, return a non-CRT key instead + if (checkComponents(key)) { + return key; + } else { + return new RSAPrivateKeyImpl(key.type, key.keyParams, + key.getModulus(), key.getPrivateExponent()); + } + case "PKCS#1": + try { + BigInteger[] comps = parseASN1(encoded); + if ((comps[1].signum() == 0) || (comps[3].signum() == 0) || + (comps[4].signum() == 0) || (comps[5].signum() == 0) || + (comps[6].signum() == 0) || (comps[7].signum() == 0)) { + return new RSAPrivateKeyImpl(type, null, comps[0], + comps[2]); + } else { + return new RSAPrivateCrtKeyImpl(type, null, comps[0], + comps[1], comps[2], comps[3], comps[4], comps[5], + comps[6], comps[7]); + } + } catch (IOException ioe) { + throw new InvalidKeyException("Invalid PKCS#1 encoding", ioe); + } + default: + throw new InvalidKeyException("Unsupported RSA Private(Crt)Key " + + "format: " + format); } } @@ -113,14 +139,13 @@ BigInteger p, BigInteger q, BigInteger pe, BigInteger qe, BigInteger coeff) throws InvalidKeyException { RSAPrivateKey key; - AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params); if ((e.signum() == 0) || (p.signum() == 0) || (q.signum() == 0) || (pe.signum() == 0) || (qe.signum() == 0) || (coeff.signum() == 0)) { // if any component is missing, return a non-CRT key - return new RSAPrivateKeyImpl(rsaId, n, d); + return new RSAPrivateKeyImpl(type, params, n, d); } else { - return new RSAPrivateCrtKeyImpl(rsaId, n, e, d, + return new RSAPrivateCrtKeyImpl(type, params, n, e, d, p, q, pe, qe, coeff); } } @@ -128,7 +153,7 @@ /** * Construct a key from its encoding. Called from newKey above. */ - RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException { + private RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException { if (encoded == null || encoded.length == 0) { throw new InvalidKeyException("Missing key encoding"); } @@ -136,8 +161,10 @@ decode(encoded); RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); try { - // this will check the validity of params - this.keyParams = RSAUtil.getParamSpec(algid); + // check the validity of oid and params + Object[] o = RSAUtil.getTypeAndParamSpec(algid); + this.type = (KeyType) o[0]; + this.keyParams = (AlgorithmParameterSpec) o[1]; } catch (ProviderException e) { throw new InvalidKeyException(e); } @@ -147,7 +174,7 @@ * Construct a RSA key from its components. Used by the * RSAKeyFactory and the RSAKeyPairGenerator. */ - RSAPrivateCrtKeyImpl(AlgorithmId rsaId, + RSAPrivateCrtKeyImpl(KeyType type, AlgorithmParameterSpec keyParams, BigInteger n, BigInteger e, BigInteger d, BigInteger p, BigInteger q, BigInteger pe, BigInteger qe, BigInteger coeff) throws InvalidKeyException { @@ -161,11 +188,19 @@ this.pe = pe; this.qe = qe; this.coeff = coeff; - this.keyParams = RSAUtil.getParamSpec(rsaId); - // generate the encoding - algid = rsaId; try { + // validate and generate the algid encoding + algid = RSAUtil.createAlgorithmId(type, keyParams); + } catch (ProviderException exc) { + throw new InvalidKeyException(exc); + } + + this.type = type; + this.keyParams = keyParams; + + try { + // generate the key encoding DerOutputStream out = new DerOutputStream(); out.putInteger(0); // version must be 0 out.putInteger(n); @@ -188,7 +223,7 @@ // see JCA doc @Override public String getAlgorithm() { - return algid.getName(); + return type.keyAlgo; } // see JCA doc @@ -248,9 +283,39 @@ // return a string representation of this key for debugging @Override public String toString() { - return "SunRsaSign " + getAlgorithm() + " private CRT key, " + n.bitLength() - + " bits" + "\n params: " + keyParams + "\n modulus: " + n - + "\n private exponent: " + d; + return "SunRsaSign " + type.keyAlgo + " private CRT key, " + + n.bitLength() + " bits" + "\n params: " + keyParams + + "\n modulus: " + n + "\n private exponent: " + d; + } + + // utility method for parsing DER encoding of RSA private keys in PKCS#1 + // format as defined in RFC 8017 Appendix A.1.2, i.e. SEQ of version, n, + // e, d, p, q, pe, qe, and coeff, and return the parsed components. + private static BigInteger[] parseASN1(byte[] raw) throws IOException { + DerValue derValue = new DerValue(raw); + if (derValue.tag != DerValue.tag_Sequence) { + throw new IOException("Not a SEQUENCE"); + } + int version = derValue.data.getInteger(); + if (version != 0) { + throw new IOException("Version must be 0"); + } + + BigInteger[] result = new BigInteger[8]; // n, e, d, p, q, pe, qe, coeff + /* + * Some implementations do not correctly encode ASN.1 INTEGER values + * in 2's complement format, resulting in a negative integer when + * decoded. Correct the error by converting it to a positive integer. + * + * See CR 6255949 + */ + for (int i = 0; i < result.length; i++) { + result[i] = derValue.data.getPositiveBigInteger(); + } + if (derValue.data.available() != 0) { + throw new IOException("Extra data available"); + } + return result; } /** @@ -258,37 +323,32 @@ */ protected void parseKeyBits() throws InvalidKeyException { try { - DerInputStream in = new DerInputStream(key); - DerValue derValue = in.getDerValue(); - if (derValue.tag != DerValue.tag_Sequence) { - throw new IOException("Not a SEQUENCE"); - } - DerInputStream data = derValue.data; - int version = data.getInteger(); - if (version != 0) { - throw new IOException("Version must be 0"); - } - - /* - * Some implementations do not correctly encode ASN.1 INTEGER values - * in 2's complement format, resulting in a negative integer when - * decoded. Correct the error by converting it to a positive integer. - * - * See CR 6255949 - */ - n = data.getPositiveBigInteger(); - e = data.getPositiveBigInteger(); - d = data.getPositiveBigInteger(); - p = data.getPositiveBigInteger(); - q = data.getPositiveBigInteger(); - pe = data.getPositiveBigInteger(); - qe = data.getPositiveBigInteger(); - coeff = data.getPositiveBigInteger(); - if (derValue.data.available() != 0) { - throw new IOException("Extra data available"); - } + BigInteger[] comps = parseASN1(key); + n = comps[0]; + e = comps[1]; + d = comps[2]; + p = comps[3]; + q = comps[4]; + pe = comps[5]; + qe = comps[6]; + coeff = comps[7]; } catch (IOException e) { throw new InvalidKeyException("Invalid RSA private key", e); } } + + /** + * Restores the state of this object from the stream. + *

+ * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "RSAPrivateCrtKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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 @@ -26,6 +26,8 @@ package sun.security.rsa; import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.*; @@ -33,15 +35,17 @@ import java.security.interfaces.*; import sun.security.util.*; -import sun.security.x509.AlgorithmId; import sun.security.pkcs.PKCS8Key; +import sun.security.rsa.RSAUtil.KeyType; + /** * RSA private key implementation for "RSA", "RSASSA-PSS" algorithms in non-CRT - * form (modulus, private exponent only). For CRT private keys, see - * RSAPrivateCrtKeyImpl. We need separate classes to ensure correct behavior - * in instanceof checks, etc. - * + * form (modulus, private exponent only). + *

+ * For CRT private keys, see RSAPrivateCrtKeyImpl. We need separate classes + * to ensure correct behavior in instanceof checks, etc. + *

* Note: RSA keys must be at least 512 bits long * * @see RSAPrivateCrtKeyImpl @@ -57,26 +61,37 @@ private final BigInteger n; // modulus private final BigInteger d; // private exponent + private transient final KeyType type; + // optional parameters associated with this RSA key // specified in the encoding of its AlgorithmId. // must be null for "RSA" keys. - private final AlgorithmParameterSpec keyParams; + private transient final AlgorithmParameterSpec keyParams; /** * Construct a key from its components. Used by the * RSAKeyFactory and the RSAKeyPairGenerator. */ - RSAPrivateKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger d) - throws InvalidKeyException { + RSAPrivateKeyImpl(KeyType type, AlgorithmParameterSpec keyParams, + BigInteger n, BigInteger d) throws InvalidKeyException { + RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), null); this.n = n; this.d = d; - this.keyParams = RSAUtil.getParamSpec(rsaId); - // generate the encoding - algid = rsaId; try { + // validate and generate the algid encoding + algid = RSAUtil.createAlgorithmId(type, keyParams); + } catch (ProviderException pe) { + throw new InvalidKeyException(pe); + } + + this.type = type; + this.keyParams = keyParams; + + try { + // generate the key encoding DerOutputStream out = new DerOutputStream(); out.putInteger(0); // version must be 0 out.putInteger(n); @@ -99,7 +114,7 @@ // see JCA doc @Override public String getAlgorithm() { - return algid.getName(); + return type.keyAlgo; } // see JCA doc @@ -123,8 +138,23 @@ // return a string representation of this key for debugging @Override public String toString() { - return "Sun " + getAlgorithm() + " private key, " + n.bitLength() + return "Sun " + type.keyAlgo + " private key, " + n.bitLength() + " bits" + "\n params: " + keyParams + "\n modulus: " + n + "\n private exponent: " + d; } + + /** + * Restores the state of this object from the stream. + *

+ * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "RSAPrivateKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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 @@ -26,6 +26,8 @@ package sun.security.rsa; import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.*; @@ -34,13 +36,12 @@ import sun.security.util.*; import sun.security.x509.X509Key; -import sun.security.x509.AlgorithmId; -import static sun.security.rsa.RSAUtil.KeyType; +import sun.security.rsa.RSAUtil.KeyType; /** * RSA public key implementation for "RSA", "RSASSA-PSS" algorithms. - * + *

* Note: RSA keys must be at least 512 bits long * * @see RSAPrivateCrtKeyImpl @@ -58,47 +59,76 @@ private BigInteger n; // modulus private BigInteger e; // public exponent + private transient KeyType type; + // optional parameters associated with this RSA key // specified in the encoding of its AlgorithmId // must be null for "RSA" keys. - private AlgorithmParameterSpec keyParams; + private transient AlgorithmParameterSpec keyParams; /** - * Generate a new RSAPublicKey from the specified encoding. - * Used by SunPKCS11 provider. + * Generate a new RSAPublicKey from the specified type, format, and + * encoding. + * Also used by SunPKCS11 provider. */ - public static RSAPublicKey newKey(byte[] encoded) - throws InvalidKeyException { - return new RSAPublicKeyImpl(encoded); + public static RSAPublicKey newKey(KeyType type, String format, + byte[] encoded) throws InvalidKeyException { + RSAPublicKey key; + switch (format) { + case "X.509": + key = new RSAPublicKeyImpl(encoded); + RSAKeyFactory.checkKeyAlgo(key, type.keyAlgo); + break; + case "PKCS#1": + try { + BigInteger[] comps = parseASN1(encoded); + key = new RSAPublicKeyImpl(type, null, comps[0], comps[1]); + } catch (IOException ioe) { + throw new InvalidKeyException("Invalid PKCS#1 encoding", ioe); + } + break; + default: + throw new InvalidKeyException("Unsupported RSA PublicKey format: " + + format); + } + return key; } /** * Generate a new RSAPublicKey from the specified type and components. - * Used by SunPKCS11 provider. + * Also used by SunPKCS11 provider. */ public static RSAPublicKey newKey(KeyType type, AlgorithmParameterSpec params, BigInteger n, BigInteger e) throws InvalidKeyException { - AlgorithmId rsaId = RSAUtil.createAlgorithmId(type, params); - return new RSAPublicKeyImpl(rsaId, n, e); + return new RSAPublicKeyImpl(type, params, n, e); } /** - * Construct a RSA key from AlgorithmId and its components. Used by + * Construct a RSA key from the specified type and components. Used by * RSAKeyFactory and RSAKeyPairGenerator. */ - RSAPublicKeyImpl(AlgorithmId rsaId, BigInteger n, BigInteger e) - throws InvalidKeyException { + RSAPublicKeyImpl(KeyType type, AlgorithmParameterSpec keyParams, + BigInteger n, BigInteger e) throws InvalidKeyException { + RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e); checkExponentRange(n, e); this.n = n; this.e = e; - this.keyParams = RSAUtil.getParamSpec(rsaId); - // generate the encoding - algid = rsaId; try { + // validate and generate algid encoding + algid = RSAUtil.createAlgorithmId(type, keyParams); + } catch (ProviderException pe) { + throw new InvalidKeyException(pe); + } + + this.type = type; + this.keyParams = keyParams; + + try { + // generate the key encoding DerOutputStream out = new DerOutputStream(); out.putInteger(n); out.putInteger(e); @@ -113,9 +143,9 @@ } /** - * Construct a key from its encoding. Used by RSAKeyFactory. + * Construct a key from its encoding. */ - RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException { + private RSAPublicKeyImpl(byte[] encoded) throws InvalidKeyException { if (encoded == null || encoded.length == 0) { throw new InvalidKeyException("Missing key encoding"); } @@ -124,8 +154,10 @@ checkExponentRange(n, e); try { - // this will check the validity of params - this.keyParams = RSAUtil.getParamSpec(algid); + // check the validity of oid and params + Object[] o = RSAUtil.getTypeAndParamSpec(algid); + this.type = (KeyType) o[0]; + this.keyParams = (AlgorithmParameterSpec) o[1]; } catch (ProviderException e) { throw new InvalidKeyException(e); } @@ -148,7 +180,7 @@ // see JCA doc @Override public String getAlgorithm() { - return algid.getName(); + return type.keyAlgo; } // see JCA doc @@ -169,22 +201,30 @@ return keyParams; } + // utility method for parsing DER encoding of RSA public keys in PKCS#1 + // format as defined in RFC 8017 Appendix A.1.1, i.e. SEQ of n and e. + private static BigInteger[] parseASN1(byte[] raw) throws IOException { + DerValue derValue = new DerValue(raw); + if (derValue.tag != DerValue.tag_Sequence) { + throw new IOException("Not a SEQUENCE"); + } + BigInteger[] result = new BigInteger[2]; // n, e + result[0] = derValue.data.getPositiveBigInteger(); + result[1] = derValue.data.getPositiveBigInteger(); + if (derValue.data.available() != 0) { + throw new IOException("Extra data available"); + } + return result; + } + /** * Parse the key. Called by X509Key. */ protected void parseKeyBits() throws InvalidKeyException { try { - DerInputStream in = new DerInputStream(getKey().toByteArray()); - DerValue derValue = in.getDerValue(); - if (derValue.tag != DerValue.tag_Sequence) { - throw new IOException("Not a SEQUENCE"); - } - DerInputStream data = derValue.data; - n = data.getPositiveBigInteger(); - e = data.getPositiveBigInteger(); - if (derValue.data.available() != 0) { - throw new IOException("Extra data available"); - } + BigInteger[] comps = parseASN1(getKey().toByteArray()); + n = comps[0]; + e = comps[1]; } catch (IOException e) { throw new InvalidKeyException("Invalid RSA public key", e); } @@ -193,15 +233,30 @@ // return a string representation of this key for debugging @Override public String toString() { - return "Sun " + getAlgorithm() + " public key, " + n.bitLength() + return "Sun " + type.keyAlgo + " public key, " + n.bitLength() + " bits" + "\n params: " + keyParams + "\n modulus: " + n + "\n public exponent: " + e; } - protected Object writeReplace() throws java.io.ObjectStreamException { + private Object writeReplace() throws java.io.ObjectStreamException { return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded()); } + + /** + * Restores the state of this object from the stream. + *

+ * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "RSAPublicKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAUtil.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAUtil.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/RSAUtil.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/RSAUtil.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -40,52 +40,71 @@ public class RSAUtil { public enum KeyType { - RSA ("RSA"), - PSS ("RSASSA-PSS") + RSA ("RSA", AlgorithmId.RSAEncryption_oid, null), + PSS ("RSASSA-PSS", AlgorithmId.RSASSA_PSS_oid, PSSParameterSpec.class) ; - private final String algo; - - KeyType(String keyAlgo) { - this.algo = keyAlgo; - } - public String keyAlgo() { - return algo; - } - public static KeyType lookup(String name) - throws InvalidKeyException, ProviderException { - if (name == null) { - throw new InvalidKeyException("Null key algorithm"); + final String keyAlgo; + final ObjectIdentifier oid; + final Class paramSpecCls; + + KeyType(String keyAlgo, ObjectIdentifier oid, + Class paramSpecCls) { + this.keyAlgo = keyAlgo; + this.oid = oid; + this.paramSpecCls = paramSpecCls; + } + + public static KeyType lookup(String name) throws ProviderException { + + requireNonNull(name, "Key algorithm should not be null"); + + // match loosely in order to work with 3rd party providers which + // may not follow the standard names + if (name.indexOf("PSS") != -1) { + return PSS; + } else if (name.indexOf("RSA") != -1) { + return RSA; + } else { // no match + throw new ProviderException("Unsupported algorithm " + name); } - for (KeyType kt : KeyType.values()) { - if (kt.keyAlgo().equalsIgnoreCase(name)) { - return kt; - } - } - // no match - throw new ProviderException("Unsupported algorithm " + name); } } - public static void checkParamsAgainstType(KeyType type, + private static void requireNonNull(Object obj, String msg) { + if (obj == null) throw new ProviderException(msg); + } + + public static AlgorithmParameterSpec checkParamsAgainstType(KeyType type, AlgorithmParameterSpec paramSpec) throws ProviderException { - switch (type) { - case RSA: - if (paramSpec != null) { - throw new ProviderException("null params expected for " + - type.keyAlgo()); - } - break; - case PSS: - if ((paramSpec != null) && - !(paramSpec instanceof PSSParameterSpec)) { - throw new ProviderException - ("PSSParmeterSpec expected for " + type.keyAlgo()); - } - break; - default: - throw new ProviderException - ("Unsupported RSA algorithm " + type); + + // currently no check for null parameter spec + // assumption is parameter spec is optional and can be null + if (paramSpec == null) return null; + + Class expCls = type.paramSpecCls; + if (expCls == null) { + throw new ProviderException("null params expected for " + + type.keyAlgo); + } else if (!expCls.isInstance(paramSpec)) { + throw new ProviderException + (expCls + " expected for " + type.keyAlgo); + } + return paramSpec; + } + + public static AlgorithmParameters getParams(KeyType type, + AlgorithmParameterSpec spec) throws ProviderException { + + if (spec == null) return null; + + try { + AlgorithmParameters params = + AlgorithmParameters.getInstance(type.keyAlgo); + params.init(spec); + return params; + } catch (NoSuchAlgorithmException | InvalidParameterSpecException ex) { + throw new ProviderException(ex); } } @@ -94,69 +113,53 @@ checkParamsAgainstType(type, paramSpec); - ObjectIdentifier oid = null; - AlgorithmParameters params = null; - try { - switch (type) { - case RSA: - oid = AlgorithmId.RSAEncryption_oid; - break; - case PSS: - if (paramSpec != null) { - params = AlgorithmParameters.getInstance(type.keyAlgo()); - params.init(paramSpec); - } - oid = AlgorithmId.RSASSA_PSS_oid; - break; - default: - throw new ProviderException - ("Unsupported RSA algorithm " + type); - } - AlgorithmId result; - if (params == null) { - result = new AlgorithmId(oid); - } else { - result = new AlgorithmId(oid, params); - } - return result; - } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) { - // should not happen - throw new ProviderException(e); - } + ObjectIdentifier oid = type.oid; + AlgorithmParameters params = getParams(type, paramSpec); + return new AlgorithmId(oid, params); } - public static AlgorithmParameterSpec getParamSpec(AlgorithmId algid) - throws ProviderException { - if (algid == null) { - throw new ProviderException("AlgorithmId should not be null"); + public static AlgorithmParameterSpec getParamSpec( + AlgorithmParameters params) throws ProviderException { + + if (params == null) return null; + + String algName = params.getAlgorithm(); + + KeyType type = KeyType.lookup(algName); + Class specCls = type.paramSpecCls; + if (specCls == null) { + throw new ProviderException("No params accepted for " + + type.keyAlgo); + } + try { + return params.getParameterSpec(specCls); + } catch (InvalidParameterSpecException ex) { + throw new ProviderException(ex); } - return getParamSpec(algid.getParameters()); } - public static AlgorithmParameterSpec getParamSpec(AlgorithmParameters params) + public static Object[] getTypeAndParamSpec(AlgorithmId algid) throws ProviderException { - if (params == null) return null; + requireNonNull(algid, "AlgorithmId should not be null"); + + Object[] result = new Object[2]; + + String algName = algid.getName(); try { - String algName = params.getAlgorithm(); - KeyType type = KeyType.lookup(algName); - Class specCls; - switch (type) { - case RSA: - throw new ProviderException("No params accepted for " + - type.keyAlgo()); - case PSS: - specCls = PSSParameterSpec.class; - break; - default: - throw new ProviderException("Unsupported RSA algorithm: " + algName); - } - return params.getParameterSpec(specCls); + result[0] = KeyType.lookup(algName); } catch (ProviderException pe) { - // pass it up - throw pe; - } catch (Exception e) { - throw new ProviderException(e); + // accommodate RSA keys encoded with various RSA signature oids + // for backward compatibility + if (algName.indexOf("RSA") != -1) { + result[0] = KeyType.RSA; + } else { + // pass it up + throw pe; + } } + + result[1] = getParamSpec(algid.getParameters()); + return result; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -27,7 +27,7 @@ import java.util.*; import java.security.Provider; -import static sun.security.provider.SunEntries.createAliasesWithOid; +import static sun.security.util.SecurityProviderConstants.getAliases; /** * Defines the entries of the SunRsaSign provider. @@ -38,7 +38,14 @@ private void add(Provider p, String type, String algo, String cn, List aliases, HashMap attrs) { - services.add(new Provider.Service(p, type, algo, cn, aliases, attrs)); + services.add(new Provider.Service(p, type, algo, cn, + aliases, attrs)); + } + + private void addA(Provider p, String type, String algo, String cn, + HashMap attrs) { + services.add(new Provider.Service(p, type, algo, cn, + getAliases(algo), attrs)); } // extend LinkedHashSet for consistency with SunEntries @@ -47,13 +54,6 @@ services = new LinkedHashSet<>(20, 0.9f); // start populating content using the specified provider - - // common oids - String rsaOid = "1.2.840.113549.1.1"; - List rsaAliases = createAliasesWithOid(rsaOid); - List rsapssAliases = createAliasesWithOid(rsaOid + ".10"); - String sha1withRSAOid2 = "1.3.14.3.2.29"; - // common attribute map HashMap attrs = new HashMap<>(3); attrs.put("SupportedKeyClasses", @@ -62,50 +62,37 @@ add(p, "KeyFactory", "RSA", "sun.security.rsa.RSAKeyFactory$Legacy", - rsaAliases, null); + getAliases("PKCS1"), null); add(p, "KeyPairGenerator", "RSA", "sun.security.rsa.RSAKeyPairGenerator$Legacy", - rsaAliases, null); - add(p, "Signature", "MD2withRSA", - "sun.security.rsa.RSASignature$MD2withRSA", - createAliasesWithOid(rsaOid + ".2"), attrs); - add(p, "Signature", "MD5withRSA", - "sun.security.rsa.RSASignature$MD5withRSA", - createAliasesWithOid(rsaOid + ".4"), attrs); - add(p, "Signature", "SHA1withRSA", - "sun.security.rsa.RSASignature$SHA1withRSA", - createAliasesWithOid(rsaOid + ".5", sha1withRSAOid2), attrs); - add(p, "Signature", "SHA224withRSA", - "sun.security.rsa.RSASignature$SHA224withRSA", - createAliasesWithOid(rsaOid + ".14"), attrs); - add(p, "Signature", "SHA256withRSA", - "sun.security.rsa.RSASignature$SHA256withRSA", - createAliasesWithOid(rsaOid + ".11"), attrs); - add(p, "Signature", "SHA384withRSA", - "sun.security.rsa.RSASignature$SHA384withRSA", - createAliasesWithOid(rsaOid + ".12"), attrs); - add(p, "Signature", "SHA512withRSA", - "sun.security.rsa.RSASignature$SHA512withRSA", - createAliasesWithOid(rsaOid + ".13"), attrs); - add(p, "Signature", "SHA512/224withRSA", - "sun.security.rsa.RSASignature$SHA512_224withRSA", - createAliasesWithOid(rsaOid + ".15"), attrs); - add(p, "Signature", "SHA512/256withRSA", - "sun.security.rsa.RSASignature$SHA512_256withRSA", - createAliasesWithOid(rsaOid + ".16"), attrs); - - add(p, "KeyFactory", "RSASSA-PSS", - "sun.security.rsa.RSAKeyFactory$PSS", - rsapssAliases, null); - add(p, "KeyPairGenerator", "RSASSA-PSS", - "sun.security.rsa.RSAKeyPairGenerator$PSS", - rsapssAliases, null); - add(p, "Signature", "RSASSA-PSS", - "sun.security.rsa.RSAPSSSignature", - rsapssAliases, attrs); - add(p, "AlgorithmParameters", "RSASSA-PSS", - "sun.security.rsa.PSSParameters", - rsapssAliases, null); + getAliases("PKCS1"), null); + addA(p, "Signature", "MD2withRSA", + "sun.security.rsa.RSASignature$MD2withRSA", attrs); + addA(p, "Signature", "MD5withRSA", + "sun.security.rsa.RSASignature$MD5withRSA", attrs); + addA(p, "Signature", "SHA1withRSA", + "sun.security.rsa.RSASignature$SHA1withRSA", attrs); + addA(p, "Signature", "SHA224withRSA", + "sun.security.rsa.RSASignature$SHA224withRSA", attrs); + addA(p, "Signature", "SHA256withRSA", + "sun.security.rsa.RSASignature$SHA256withRSA", attrs); + addA(p, "Signature", "SHA384withRSA", + "sun.security.rsa.RSASignature$SHA384withRSA", attrs); + addA(p, "Signature", "SHA512withRSA", + "sun.security.rsa.RSASignature$SHA512withRSA", attrs); + addA(p, "Signature", "SHA512/224withRSA", + "sun.security.rsa.RSASignature$SHA512_224withRSA", attrs); + addA(p, "Signature", "SHA512/256withRSA", + "sun.security.rsa.RSASignature$SHA512_256withRSA", attrs); + + addA(p, "KeyFactory", "RSASSA-PSS", + "sun.security.rsa.RSAKeyFactory$PSS", attrs); + addA(p, "KeyPairGenerator", "RSASSA-PSS", + "sun.security.rsa.RSAKeyPairGenerator$PSS", attrs); + addA(p, "Signature", "RSASSA-PSS", + "sun.security.rsa.RSAPSSSignature", attrs); + addA(p, "AlgorithmParameters", "RSASSA-PSS", + "sun.security.rsa.PSSParameters", attrs); } public Iterator iterator() { diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java 2023-10-06 05:33:33.000000000 +0000 @@ -327,45 +327,36 @@ } /* - * 768 bits ephemeral DH private keys were used to be used in + * 768 bit ephemeral DH private keys used to be used in * ServerKeyExchange except that exportable ciphers max out at 512 - * bits modulus values. We still adhere to this behavior in legacy + * bit modulus values. We still adhere to this behavior in legacy * mode (system property "jdk.tls.ephemeralDHKeySize" is defined * as "legacy"). * - * Old JDK (JDK 7 and previous) releases don't support DH keys - * bigger than 1024 bits. We have to consider the compatibility - * requirement. 1024 bits DH key is always used for non-exportable - * cipher suites in default mode (system property + * Only very old JDK releases don't support DH keys bigger than + * 1024 bits (JDK 1.5 and 6u/7u releases prior to adding support + * for DH keys > 1024 bits - see JDK-8062834). A 2048 bit + * DH key is always used for non-exportable cipher suites in + * default mode (when the system property * "jdk.tls.ephemeralDHKeySize" is not defined). * - * However, if applications want more stronger strength, setting - * system property "jdk.tls.ephemeralDHKeySize" to "matched" - * is a workaround to use ephemeral DH key which size matches the - * corresponding authentication key. For example, if the public key - * size of an authentication certificate is 2048 bits, then the - * ephemeral DH key size should be 2048 bits accordingly unless - * the cipher suite is exportable. This key sizing scheme keeps - * the cryptographic strength consistent between authentication - * keys and key-exchange keys. - * * Applications may also want to customize the ephemeral DH key * size to a fixed length for non-exportable cipher suites. This - * can be approached by setting system property + * can be done by setting the system property * "jdk.tls.ephemeralDHKeySize" to a valid positive integer between * 1024 and 8192 bits, inclusive. * - * Note that the minimum acceptable key size is 1024 bits except - * exportable cipher suites or legacy mode. + * Note that the minimum acceptable key size is 2048 bits except + * for exportable cipher suites or legacy mode. * * Note that per RFC 2246, the key size limit of DH is 512 bits for * exportable cipher suites. Because of the weakness, exportable * cipher suites are deprecated since TLS v1.1 and they are not * enabled by default in Oracle provider. The legacy behavior is - * reserved and 512 bits DH key is always used for exportable + * preserved and a 512 bit DH key is always used for exportable * cipher suites. */ - int keySize = exportable ? 512 : 1024; // default mode + int keySize = exportable ? 512 : 2048; // default mode if (!exportable) { if (useLegacyEphemeralDHKeys) { // legacy mode keySize = 768; @@ -391,7 +382,7 @@ // limit in the future when the compatibility and // interoperability impact is limited. keySize = ks <= 1024 ? 1024 : 2048; - } // Otherwise, anonymous cipher suites, 1024-bit is used. + } // Otherwise, anonymous cipher suites, 2048-bit is used. } else if (customizedDHKeySize > 0) { // customized mode keySize = customizedDHKeySize; } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java 2023-10-06 05:33:33.000000000 +0000 @@ -143,7 +143,7 @@ this.identificationProtocol = null; this.serverNames = Collections.emptyList(); this.sniMatchers = Collections.emptyList(); - this.preferLocalCipherSuites = false; + this.preferLocalCipherSuites = true; this.applicationProtocols = new String[0]; this.enableRetransmissions = sslContext.isDTLS(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/SunJSSE.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/SunJSSE.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/SunJSSE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/SunJSSE.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -29,7 +29,7 @@ import java.util.*; import sun.security.rsa.SunRsaSignEntries; import static sun.security.util.SecurityConstants.PROVIDER_VER; -import static sun.security.provider.SunEntries.createAliases; +import static sun.security.util.SecurityProviderConstants.*; /** * The JSSE provider. @@ -161,8 +161,8 @@ } private void ps(String type, String algo, String cn, - List aliases, HashMap attrs) { - putService(new Provider.Service(this, type, algo, cn, aliases, attrs)); + List a, HashMap attrs) { + putService(new Provider.Service(this, type, algo, cn, a, attrs)); } private void doRegister(boolean isfips) { @@ -180,17 +180,17 @@ "sun.security.ssl.KeyManagerFactoryImpl$SunX509", null, null); ps("KeyManagerFactory", "NewSunX509", "sun.security.ssl.KeyManagerFactoryImpl$X509", - createAliases("PKIX"), null); + List.of("PKIX"), null); ps("TrustManagerFactory", "SunX509", "sun.security.ssl.TrustManagerFactoryImpl$SimpleFactory", null, null); ps("TrustManagerFactory", "PKIX", "sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", - createAliases("SunPKIX", "X509", "X.509"), null); + List.of("SunPKIX", "X509", "X.509"), null); ps("SSLContext", "TLSv1", "sun.security.ssl.SSLContextImpl$TLS10Context", - (isfips? null : createAliases("SSLv3")), null); + (isfips? null : List.of("SSLv3")), null); ps("SSLContext", "TLSv1.1", "sun.security.ssl.SSLContextImpl$TLS11Context", null, null); ps("SSLContext", "TLSv1.2", @@ -199,7 +199,7 @@ "sun.security.ssl.SSLContextImpl$TLS13Context", null, null); ps("SSLContext", "TLS", "sun.security.ssl.SSLContextImpl$TLSContext", - (isfips? null : createAliases("SSL")), null); + (isfips? null : List.of("SSL")), null); ps("SSLContext", "DTLSv1.0", "sun.security.ssl.SSLContextImpl$DTLS10Context", null, null); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -43,6 +43,7 @@ import javax.net.ssl.*; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.validator.Validator; +import sun.security.util.KnownOIDs; /** * The new X509 key manager implementation. The main differences to the @@ -521,14 +522,19 @@ // enum constant for "tls client" check // valid EKU for TLS client: any, tls_client - CLIENT(new HashSet(Arrays.asList(new String[] { - "2.5.29.37.0", "1.3.6.1.5.5.7.3.2" }))), + CLIENT(new HashSet(List.of( + KnownOIDs.anyExtendedKeyUsage.value(), + KnownOIDs.clientAuth.value() + ))), // enum constant for "tls server" check // valid EKU for TLS server: any, tls_server, ns_sgc, ms_sgc - SERVER(new HashSet(Arrays.asList(new String[] { - "2.5.29.37.0", "1.3.6.1.5.5.7.3.1", "2.16.840.1.113730.4.1", - "1.3.6.1.4.1.311.10.3.3" }))); + SERVER(new HashSet(List.of( + KnownOIDs.anyExtendedKeyUsage.value(), + KnownOIDs.serverAuth.value(), + KnownOIDs.NETSCAPE_ExportApproved.value(), + KnownOIDs.MICROSOFT_ExportApproved.value() + ))); // set of valid EKU values for this type final Set validEku; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/timestamp/TSRequest.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/timestamp/TSRequest.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/timestamp/TSRequest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/timestamp/TSRequest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -163,7 +163,7 @@ // encode optional elements if (policyId != null) { - request.putOID(new ObjectIdentifier(policyId)); + request.putOID(ObjectIdentifier.of(policyId)); } if (nonce != null) { request.putInteger(nonce); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/tools/keytool/Main.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/tools/keytool/Main.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/tools/keytool/Main.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/tools/keytool/Main.java 2023-10-06 05:33:33.000000000 +0000 @@ -4278,6 +4278,23 @@ } /** + * Match a command with a command set. The match can be exact, or + * partial, or case-insensitive. + * + * @param s the command provided by user + * @param list the legal command set represented by KnownOIDs enums. + * @return the position of a single match, or -1 if none matched + * @throws Exception if s is ambiguous + */ + private static int oneOf(String s, KnownOIDs... list) throws Exception { + String[] convertedList = new String[list.length]; + for (int i = 0; i < list.length; i++) { + convertedList[i] = list[i].stdName(); + } + return oneOf(s, convertedList); + } + + /** * Match a command (may be abbreviated) with a command set. * @param s the command provided * @param list the legal command set. If there is a null, commands after it @@ -4395,7 +4412,7 @@ case 5: return PKIXExtensions.SubjectInfoAccess_Id; case 6: return PKIXExtensions.AuthInfoAccess_Id; case 8: return PKIXExtensions.CRLDistributionPoints_Id; - default: return new ObjectIdentifier(type); + default: return ObjectIdentifier.of(type); } } @@ -4616,30 +4633,26 @@ case 2: // EKU if(value != null) { Vector v = new Vector<>(); + KnownOIDs[] choices = { + KnownOIDs.anyExtendedKeyUsage, + KnownOIDs.serverAuth, + KnownOIDs.clientAuth, + KnownOIDs.codeSigning, + KnownOIDs.emailProtection, + KnownOIDs.KP_TimeStamping, + KnownOIDs.OCSPSigning + }; for (String s: value.split(",")) { - int p = oneOf(s, - "anyExtendedKeyUsage", - "serverAuth", //1 - "clientAuth", //2 - "codeSigning", //3 - "emailProtection", //4 - "", //5 - "", //6 - "", //7 - "timeStamping", //8 - "OCSPSigning" //9 - ); - if (p < 0) { - try { - v.add(new ObjectIdentifier(s)); - } catch (Exception e) { - throw new Exception(rb.getString( - "Unknown.extendedkeyUsage.type.") + s); - } - } else if (p == 0) { - v.add(new ObjectIdentifier("2.5.29.37.0")); - } else { - v.add(new ObjectIdentifier("1.3.6.1.5.5.7.3." + p)); + int p = oneOf(s, choices); + String o = s; + if (p >= 0) { + o = choices[p].value(); + } + try { + v.add(ObjectIdentifier.of(o)); + } catch (Exception e) { + throw new Exception(rb.getString( + "Unknown.extendedkeyUsage.type.") + s); } } setExt(result, new ExtendedKeyUsageExtension(isCritical, v)); @@ -4694,24 +4707,23 @@ String m = item.substring(0, colonpos); String t = item.substring(colonpos+1, colonpos2); String v = item.substring(colonpos2+1); - int p = oneOf(m, - "", - "ocsp", //1 - "caIssuers", //2 - "timeStamping", //3 - "", - "caRepository" //5 - ); + KnownOIDs[] choices = { + KnownOIDs.OCSP, + KnownOIDs.caIssuers, + KnownOIDs.AD_TimeStamping, + KnownOIDs.caRepository + }; + int p = oneOf(m, choices); ObjectIdentifier oid; - if (p < 0) { + if (p >= 0) { + oid = ObjectIdentifier.of(choices[p]); + } else { try { - oid = new ObjectIdentifier(m); + oid = ObjectIdentifier.of(m); } catch (Exception e) { throw new Exception(rb.getString( "Unknown.AccessDescription.type.") + m); } - } else { - oid = new ObjectIdentifier("1.3.6.1.5.5.7.48." + p); } accessDescriptions.add(new AccessDescription( oid, createGeneralName(t, v, exttype))); @@ -4748,7 +4760,7 @@ } break; case -1: - ObjectIdentifier oid = new ObjectIdentifier(name); + ObjectIdentifier oid = ObjectIdentifier.of(name); byte[] data = null; if (value != null) { data = new byte[value.length() / 2 + 1]; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/CurveDB.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/CurveDB.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/CurveDB.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/CurveDB.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -30,7 +30,6 @@ import java.security.spec.*; import java.util.*; -import java.util.regex.Pattern; /** * Repository for well-known Elliptic Curve parameters. It is used by both @@ -54,8 +53,6 @@ private static Collection specCollection; - public static final String SPLIT_PATTERN = ",|\\[|\\]"; - // Used by SunECEntries public static CollectiongetSupportedCurves() { return specCollection; @@ -117,9 +114,8 @@ return new BigInteger(s, 16); } - private static void add(String name, String soid, int type, String sfield, - String a, String b, String x, String y, String n, int h, - Pattern nameSplitPattern) { + private static void add(KnownOIDs o, int type, String sfield, + String a, String b, String x, String y, String n, int h) { BigInteger p = bi(sfield); ECField field; if ((type == P) || (type == PD)) { @@ -133,15 +129,16 @@ EllipticCurve curve = new EllipticCurve(field, bi(a), bi(b)); ECPoint g = new ECPoint(bi(x), bi(y)); - NamedCurve params = new NamedCurve(name, soid, curve, g, bi(n), h); - if (oidMap.put(soid, params) != null) { - throw new RuntimeException("Duplication oid: " + soid); + String oid = o.value(); + NamedCurve params = new NamedCurve(o, curve, g, bi(n), h); + if (oidMap.put(oid, params) != null) { + throw new RuntimeException("Duplication oid: " + oid); } - String[] commonNames = nameSplitPattern.split(name); - for (String commonName : commonNames) { - if (nameMap.put(commonName.trim(), params) != null) { - throw new RuntimeException("Duplication name: " + commonName); + for (String cn : params.getNameAndAliases()) { + if (nameMap.put(cn, + params) != null) { + throw new RuntimeException("Duplication name: " + cn); } } @@ -153,445 +150,424 @@ } } - private static class Holder { - private static final Pattern nameSplitPattern = Pattern.compile( - SPLIT_PATTERN); - } - - // Return all the names the EC curve could be using. - static String[] getNamesByOID(String oid) { - NamedCurve nc = oidMap.get(oid); - if (nc == null) { - return new String[0]; - } - String[] list = Holder.nameSplitPattern.split(nc.getName()); - int i = 0; - do { - list[i] = list[i].trim(); - } while (++i < list.length); - return list; - } - static { - Pattern nameSplitPattern = Holder.nameSplitPattern; - /* SEC2 prime curves */ - add("secp112r1", "1.3.132.0.6", P, + add(KnownOIDs.secp112r1, P, "DB7C2ABF62E35E668076BEAD208B", "DB7C2ABF62E35E668076BEAD2088", "659EF8BA043916EEDE8911702B22", "09487239995A5EE76B55F9C2F098", "A89CE5AF8724C0A23E0E0FF77500", "DB7C2ABF62E35E7628DFAC6561C5", - 1, nameSplitPattern); + 1); - add("secp112r2", "1.3.132.0.7", P, + add(KnownOIDs.secp112r2, P, "DB7C2ABF62E35E668076BEAD208B", "6127C24C05F38A0AAAF65C0EF02C", "51DEF1815DB5ED74FCC34C85D709", "4BA30AB5E892B4E1649DD0928643", "adcd46f5882e3747def36e956e97", "36DF0AAFD8B8D7597CA10520D04B", - 4, nameSplitPattern); + 4); - add("secp128r1", "1.3.132.0.28", P, + add(KnownOIDs.secp128r1, P, "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", "E87579C11079F43DD824993C2CEE5ED3", "161FF7528B899B2D0C28607CA52C5B86", "CF5AC8395BAFEB13C02DA292DDED7A83", "FFFFFFFE0000000075A30D1B9038A115", - 1, nameSplitPattern); + 1); - add("secp128r2", "1.3.132.0.29", P, + add(KnownOIDs.secp128r2, P, "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", "D6031998D1B3BBFEBF59CC9BBFF9AEE1", "5EEEFCA380D02919DC2C6558BB6D8A5D", "7B6AA5D85E572983E6FB32A7CDEBC140", "27B6916A894D3AEE7106FE805FC34B44", "3FFFFFFF7FFFFFFFBE0024720613B5A3", - 4, nameSplitPattern); + 4); - add("secp160k1", "1.3.132.0.9", P, + add(KnownOIDs.secp160k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", "0000000000000000000000000000000000000000", "0000000000000000000000000000000000000007", "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", "938CF935318FDCED6BC28286531733C3F03C4FEE", "0100000000000000000001B8FA16DFAB9ACA16B6B3", - 1, nameSplitPattern); + 1); - add("secp160r1", "1.3.132.0.8", P, + add(KnownOIDs.secp160r1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", "4A96B5688EF573284664698968C38BB913CBFC82", "23A628553168947D59DCC912042351377AC5FB32", "0100000000000000000001F4C8F927AED3CA752257", - 1, nameSplitPattern); + 1); - add("secp160r2", "1.3.132.0.30", P, + add(KnownOIDs.secp160r2, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", "B4E134D3FB59EB8BAB57274904664D5AF50388BA", "52DCB034293A117E1F4FF11B30F7199D3144CE6D", "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", "0100000000000000000000351EE786A818F3A1A16B", - 1, nameSplitPattern); + 1); - add("secp192k1", "1.3.132.0.31", P, + add(KnownOIDs.secp192k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", "000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000003", "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", - 1, nameSplitPattern); + 1); - add("secp192r1 [NIST P-192, X9.62 prime192v1]", "1.2.840.10045.3.1.1", PD, + add(KnownOIDs.secp192r1, PD, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", - 1, nameSplitPattern); + 1); - add("secp224k1", "1.3.132.0.32", P, + add(KnownOIDs.secp224k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", "00000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000005", "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", - 1, nameSplitPattern); + 1); - add("secp224r1 [NIST P-224]", "1.3.132.0.33", PD, + add(KnownOIDs.secp224r1, PD, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", - 1, nameSplitPattern); + 1); - add("secp256k1", "1.3.132.0.10", P, + add(KnownOIDs.secp256k1, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000007", "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - 1, nameSplitPattern); + 1); - add("secp256r1 [NIST P-256, X9.62 prime256v1]", "1.2.840.10045.3.1.7", PD, + add(KnownOIDs.secp256r1, PD, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - 1, nameSplitPattern); + 1); - add("secp384r1 [NIST P-384]", "1.3.132.0.34", PD, + add(KnownOIDs.secp384r1, PD, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - 1, nameSplitPattern); + 1); - add("secp521r1 [NIST P-521]", "1.3.132.0.35", PD, + add(KnownOIDs.secp521r1, PD, "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - 1, nameSplitPattern); + 1); /* ANSI X9.62 prime curves */ - add("X9.62 prime192v2", "1.2.840.10045.3.1.2", P, + add(KnownOIDs.prime192v2, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", - 1, nameSplitPattern); + 1); - add("X9.62 prime192v3", "1.2.840.10045.3.1.3", P, + add(KnownOIDs.prime192v3, P, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", - 1, nameSplitPattern); + 1); - add("X9.62 prime239v1", "1.2.840.10045.3.1.4", P, + add(KnownOIDs.prime239v1, P, "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", - 1, nameSplitPattern); + 1); - add("X9.62 prime239v2", "1.2.840.10045.3.1.5", P, + add(KnownOIDs.prime239v2, P, "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", - 1, nameSplitPattern); + 1); - add("X9.62 prime239v3", "1.2.840.10045.3.1.6", P, + add(KnownOIDs.prime239v3, P, "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", - 1, nameSplitPattern); + 1); /* SEC2 binary curves */ - add("sect113r1", "1.3.132.0.4", B, + add(KnownOIDs.sect113r1, B, "020000000000000000000000000201", "003088250CA6E7C7FE649CE85820F7", "00E8BEE4D3E2260744188BE0E9C723", "009D73616F35F4AB1407D73562C10F", "00A52830277958EE84D1315ED31886", "0100000000000000D9CCEC8A39E56F", - 2, nameSplitPattern); + 2); - add("sect113r2", "1.3.132.0.5", B, + add(KnownOIDs.sect113r2, B, "020000000000000000000000000201", "00689918DBEC7E5A0DD6DFC0AA55C7", "0095E9A9EC9B297BD4BF36E059184F", "01A57A6A7B26CA5EF52FCDB8164797", "00B3ADC94ED1FE674C06E695BABA1D", "010000000000000108789B2496AF93", - 2, nameSplitPattern); + 2); - add("sect131r1", "1.3.132.0.22", B, + add(KnownOIDs.sect131r1, B, "080000000000000000000000000000010D", "07A11B09A76B562144418FF3FF8C2570B8", "0217C05610884B63B9C6C7291678F9D341", "0081BAF91FDF9833C40F9C181343638399", "078C6E7EA38C001F73C8134B1B4EF9E150", "0400000000000000023123953A9464B54D", - 2, nameSplitPattern); + 2); - add("sect131r2", "1.3.132.0.23", B, + add(KnownOIDs.sect131r2, B, "080000000000000000000000000000010D", "03E5A88919D7CAFCBF415F07C2176573B2", "04B8266A46C55657AC734CE38F018F2192", "0356DCD8F2F95031AD652D23951BB366A8", "0648F06D867940A5366D9E265DE9EB240F", "0400000000000000016954A233049BA98F", - 2, nameSplitPattern); + 2); - add("sect163k1 [NIST K-163]", "1.3.132.0.1", BD, + add(KnownOIDs.sect163k1, BD, "0800000000000000000000000000000000000000C9", "000000000000000000000000000000000000000001", "000000000000000000000000000000000000000001", "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", "0289070FB05D38FF58321F2E800536D538CCDAA3D9", "04000000000000000000020108A2E0CC0D99F8A5EF", - 2, nameSplitPattern); + 2); - add("sect163r1", "1.3.132.0.2", B, + add(KnownOIDs.sect163r1, B, "0800000000000000000000000000000000000000C9", "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", "0369979697AB43897789566789567F787A7876A654", "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", - 2, nameSplitPattern); + 2); - add("sect163r2 [NIST B-163]", "1.3.132.0.15", BD, + add(KnownOIDs.sect163r2, BD, "0800000000000000000000000000000000000000C9", "000000000000000000000000000000000000000001", "020A601907B8C953CA1481EB10512F78744A3205FD", "03F0EBA16286A2D57EA0991168D4994637E8343E36", "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", "040000000000000000000292FE77E70C12A4234C33", - 2, nameSplitPattern); + 2); - add("sect193r1", "1.3.132.0.24", B, + add(KnownOIDs.sect193r1, B, "02000000000000000000000000000000000000000000008001", "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", "01000000000000000000000000C7F34A778F443ACC920EBA49", - 2, nameSplitPattern); + 2); - add("sect193r2", "1.3.132.0.25", B, + add(KnownOIDs.sect193r2, B, "02000000000000000000000000000000000000000000008001", "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", "010000000000000000000000015AAB561B005413CCD4EE99D5", - 2, nameSplitPattern); + 2); - add("sect233k1 [NIST K-233]", "1.3.132.0.26", BD, + add(KnownOIDs.sect233k1, BD, "020000000000000000000000000000000000000004000000000000000001", "000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000001", "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", - 4, nameSplitPattern); + 4); - add("sect233r1 [NIST B-233]", "1.3.132.0.27", B, + add(KnownOIDs.sect233r1, B, "020000000000000000000000000000000000000004000000000000000001", "000000000000000000000000000000000000000000000000000000000001", "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", - 2, nameSplitPattern); + 2); - add("sect239k1", "1.3.132.0.3", B, + add(KnownOIDs.sect239k1, B, "800000000000000000004000000000000000000000000000000000000001", "000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000001", "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", - 4, nameSplitPattern); + 4); - add("sect283k1 [NIST K-283]", "1.3.132.0.16", BD, + add(KnownOIDs.sect283k1, BD, "0800000000000000000000000000000000000000000000000000000000000000000010A1", "000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000001", "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", - 4, nameSplitPattern); + 4); - add("sect283r1 [NIST B-283]", "1.3.132.0.17", B, + add(KnownOIDs.sect283r1, B, "0800000000000000000000000000000000000000000000000000000000000000000010A1", "000000000000000000000000000000000000000000000000000000000000000000000001", "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", - 2, nameSplitPattern); + 2); - add("sect409k1 [NIST K-409]", "1.3.132.0.36", BD, + add(KnownOIDs.sect409k1, BD, "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", - 4, nameSplitPattern); + 4); - add("sect409r1 [NIST B-409]", "1.3.132.0.37", B, + add(KnownOIDs.sect409r1, B, "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", - 2, nameSplitPattern); + 2); - add("sect571k1 [NIST K-571]", "1.3.132.0.38", BD, + add(KnownOIDs.sect571k1, BD, "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", - 4, nameSplitPattern); + 4); - add("sect571r1 [NIST B-571]", "1.3.132.0.39", B, + add(KnownOIDs.sect571r1, B, "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", - 2, nameSplitPattern); + 2); /* ANSI X9.62 binary curves */ - add("X9.62 c2tnb191v1", "1.2.840.10045.3.0.5", B, + add(KnownOIDs.c2tnb191v1, B, "800000000000000000000000000000000000000000000201", "2866537B676752636A68F56554E12640276B649EF7526267", "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", "40000000000000000000000004A20E90C39067C893BBB9A5", - 2, nameSplitPattern); + 2); - add("X9.62 c2tnb191v2", "1.2.840.10045.3.0.6", B, + add(KnownOIDs.c2tnb191v2, B, "800000000000000000000000000000000000000000000201", "401028774D7777C7B7666D1366EA432071274F89FF01E718", "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", "20000000000000000000000050508CB89F652824E06B8173", - 4, nameSplitPattern); + 4); - add("X9.62 c2tnb191v3", "1.2.840.10045.3.0.7", B, + add(KnownOIDs.c2tnb191v3, B, "800000000000000000000000000000000000000000000201", "6C01074756099122221056911C77D77E77A777E7E7E77FCB", "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", "155555555555555555555555610C0B196812BFB6288A3EA3", - 6, nameSplitPattern); + 6); - add("X9.62 c2tnb239v1", "1.2.840.10045.3.0.11", B, + add(KnownOIDs.c2tnb239v1, B, "800000000000000000000000000000000000000000000000001000000001", "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", - 4, nameSplitPattern); + 4); - add("X9.62 c2tnb239v2", "1.2.840.10045.3.0.12", B, + add(KnownOIDs.c2tnb239v2, B, "800000000000000000000000000000000000000000000000001000000001", "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", - 6, nameSplitPattern); + 6); - add("X9.62 c2tnb239v3", "1.2.840.10045.3.0.13", B, + add(KnownOIDs.c2tnb239v3, B, "800000000000000000000000000000000000000000000000001000000001", "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", - 0xA, nameSplitPattern); + 0xA); - add("X9.62 c2tnb359v1", "1.2.840.10045.3.0.18", B, + add(KnownOIDs.c2tnb359v1, B, "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001", "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097", "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD", "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", - 0x4C, nameSplitPattern); + 0x4C); - add("X9.62 c2tnb431r1", "1.2.840.10045.3.0.20", B, + add(KnownOIDs.c2tnb431r1, B, "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001", "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", - 0x2760, nameSplitPattern); + 0x2760); /* ANSI X9.62 binary curves from the 1998 standard but forbidden * in the 2005 version of the standard. @@ -599,77 +575,77 @@ * case we need to support them after all. */ /* - add("X9.62 c2pnb163v1", "1.2.840.10045.3.0.1", B, + add(KnownOIDs.c2pnb163v1, B, "080000000000000000000000000000000000000107", "072546B5435234A422E0789675F432C89435DE5242", "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", "07AF69989546103D79329FCC3D74880F33BBE803CB", "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", "0400000000000000000001E60FC8821CC74DAEAFC1", - 2, nameSplitPattern); + 2); - add("X9.62 c2pnb163v2", "1.2.840.10045.3.0.2", B, + add(KnownOIDs.c2pnb163v2, B, "080000000000000000000000000000000000000107", "0108B39E77C4B108BED981ED0E890E117C511CF072", "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", "079F684DDF6684C5CD258B3890021B2386DFD19FC5", "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", - 2, nameSplitPattern); + 2); - add("X9.62 c2pnb163v3", "1.2.840.10045.3.0.3", B, + add(KnownOIDs.c2pnb163v3, B, "080000000000000000000000000000000000000107", "07A526C63D3E25A256A007699F5447E32AE456B50E", "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", "05B935590C155E17EA48EB3FF3718B893DF59A05D0", "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", - 2, nameSplitPattern); + 2); - add("X9.62 c2pnb176w1", "1.2.840.10045.3.0.4", B, + add(KnownOIDs.c2pnb176w1, B, "0100000000000000000000000000000000080000000007", "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", "00010092537397ECA4F6145799D62B0A19CE06FE26AD", - 0xFF6E, nameSplitPattern); + 0xFF6E); - add("X9.62 c2pnb208w1", "1.2.840.10045.3.0.10", B, + add(KnownOIDs.c2pnb208w1, B, "010000000000000000000000000000000800000000000000000007", "0000000000000000000000000000000000000000000000000000", "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", - 0xFE48, nameSplitPattern); + 0xFE48); - add("X9.62 c2pnb272w1", "1.2.840.10045.3.0.16", B, + add(KnownOIDs.c2pnb272w1, B, "010000000000000000000000000000000000000000000000000000010000000000000B", "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", - 0xFF06, nameSplitPattern); + 0xFF06); - add("X9.62 c2pnb304w1", "1.2.840.10045.3.0.17", B, + add(KnownOIDs.c2pnb304w1, B, "010000000000000000000000000000000000000000000000000000000000000000000000000807", "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614", "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B", "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", - 0xFE2E, nameSplitPattern); + 0xFE2E); - add("X9.62 c2pnb368w1", "1.2.840.10045.3.0.19", B, + add(KnownOIDs.c2pnb368w1, B, "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007", "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F", "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310", "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", - 0xFF70, nameSplitPattern); + 0xFF70); */ /* @@ -677,68 +653,68 @@ * (Twisted curves are not included) */ - add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P, + add(KnownOIDs.brainpoolP160r1, P, "E95E4A5F737059DC60DFC7AD95B3D8139515620F", "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", "1E589A8595423412134FAA2DBDEC95C8D8675E58", "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3", "1667CB477A1A8EC338F94741669C976316DA6321", "E95E4A5F737059DC60DF5991D45029409E60FC09", - 1, nameSplitPattern); + 1); - add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P, + add(KnownOIDs.brainpoolP192r1, P, "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6", "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F", "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", - 1, nameSplitPattern); + 1); - add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P, + add(KnownOIDs.brainpoolP224r1, P, "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D", "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD", "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", - 1, nameSplitPattern); + 1); - add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P, + add(KnownOIDs.brainpoolP256r1, P, "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262", "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997", "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", - 1, nameSplitPattern); + 1); - add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P, + add(KnownOIDs.brainpoolP320r1, P, "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611", "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1", "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", - 1, nameSplitPattern); + 1); - add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P, + add(KnownOIDs.brainpoolP384r1, P, "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E", "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315", "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", - 1, nameSplitPattern); + 1); - add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P, + add(KnownOIDs.brainpoolP512r1, P, "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822", "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892", "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", - 1, nameSplitPattern); + 1); specCollection = Collections.unmodifiableCollection(oidMap.values()); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java 2023-10-06 05:33:33.000000000 +0000 @@ -261,7 +261,7 @@ if (key instanceof ECKey) { NamedCurve nc = CurveDB.lookup(((ECKey)key).getParams()); return (nc == null ? List.of() - : Arrays.asList(CurveDB.getNamesByOID(nc.getObjectId()))); + : Arrays.asList(nc.getNameAndAliases())); } else if (key instanceof XECKey) { return List.of( ((NamedParameterSpec)((XECKey)key).getParams()).getName()); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/KnownOIDs.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/KnownOIDs.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/KnownOIDs.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/KnownOIDs.java 2023-10-06 05:33:33.000000000 +0000 @@ -356,6 +356,11 @@ boolean registerNames() { return false; } }, + OIW_SHA1withRSA_Odd("1.3.14.3.2.15", "SHA1withRSA") { + @Override + boolean registerNames() { return false; } + }, + SHA_1("1.3.14.3.2.26", "SHA-1", "SHA", "SHA1"), OIW_SHA1withDSA("1.3.14.3.2.27", "SHA1withDSA") { diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/NamedCurve.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/NamedCurve.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/NamedCurve.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/NamedCurve.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -29,7 +29,7 @@ import java.math.BigInteger; import java.security.spec.*; - +import java.util.Arrays; /** * Contains Elliptic Curve parameters. @@ -39,8 +39,8 @@ */ public final class NamedCurve extends ECParameterSpec { - // friendly name for toString() output - private final String name; + // friendly names with stdName followed by aliases + private final String[] nameAndAliases; // well known OID private final String oid; @@ -48,25 +48,28 @@ // encoded form (as NamedCurve identified via OID) private final byte[] encoded; - NamedCurve(String name, String oid, EllipticCurve curve, + NamedCurve(KnownOIDs ko, EllipticCurve curve, ECPoint g, BigInteger n, int h) { super(curve, g, n, h); - this.name = name; - this.oid = oid; + String[] aliases = ko.aliases(); + this.nameAndAliases = new String[aliases.length + 1]; + nameAndAliases[0] = ko.stdName(); + System.arraycopy(aliases, 0, nameAndAliases, 1, aliases.length); - DerOutputStream out = new DerOutputStream(); + this.oid = ko.value(); + DerOutputStream out = new DerOutputStream(); try { - out.putOID(new ObjectIdentifier(oid)); + out.putOID(ObjectIdentifier.of(ko)); } catch (IOException e) { throw new RuntimeException("Internal error", e); } - encoded = out.toByteArray(); } - public String getName() { - return name; + // returns the curve's standard name followed by its aliases + public String[] getNameAndAliases() { + return nameAndAliases; } public byte[] getEncoded() { @@ -78,6 +81,17 @@ } public String toString() { - return name + " (" + oid + ")"; + StringBuilder sb = new StringBuilder(nameAndAliases[0]); + if (nameAndAliases.length > 1) { + sb.append(" ["); + int j = 1; + while (j < nameAndAliases.length - 1) { + sb.append(nameAndAliases[j++]); + sb.append(','); + } + sb.append(nameAndAliases[j] + "]"); + } + sb.append(" (" + oid + ")"); + return sb.toString(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java 2023-10-06 05:33:33.000000000 +0000 @@ -51,9 +51,7 @@ * @author Hemma Prafullchandra */ -public final -class ObjectIdentifier implements Serializable -{ +public final class ObjectIdentifier implements Serializable { /* * The maximum encoded OID length, excluding the ASN.1 encoding tag and * length. @@ -73,7 +71,6 @@ */ private static final int MAXIMUM_OID_SIZE = 4096; // 2^12 - /** * We use the DER value (no tag, no length) as the internal format * @serial @@ -119,6 +116,7 @@ * @serial */ private Object components = null; // path from root + /** * @serial */ @@ -163,15 +161,15 @@ static class HugeOidNotSupportedByOldJDK implements Serializable { private static final long serialVersionUID = 1L; - static HugeOidNotSupportedByOldJDK theOne = new HugeOidNotSupportedByOldJDK(); + static HugeOidNotSupportedByOldJDK theOne = + new HugeOidNotSupportedByOldJDK(); } /** * Constructs, from a string. This string should be of the form 1.23.56. * Validity check included. */ - public ObjectIdentifier (String oid) throws IOException - { + private ObjectIdentifier(String oid) throws IOException { int ch = '.'; int start = 0; int end = 0; @@ -267,8 +265,7 @@ * @param in DER-encoded data holding an object ID * @exception IOException indicates a decoding error */ - public ObjectIdentifier (DerInputStream in) throws IOException - { + public ObjectIdentifier(DerInputStream in) throws IOException { byte type_id; int bufferEnd; @@ -281,7 +278,7 @@ * up so that we can use in.available() to check for the end of * this value in the data stream. */ - type_id = (byte) in.getByte (); + type_id = (byte)in.getByte(); if (type_id != DerValue.tag_ObjectId) throw new IOException ( "ObjectIdentifier() -- data isn't an object ID" @@ -306,8 +303,7 @@ * the tag and length have been removed/verified * Validity check NOT included. */ - ObjectIdentifier (DerInputBuffer buf) throws IOException - { + ObjectIdentifier(DerInputBuffer buf) throws IOException { DerInputStream in = new DerInputStream(buf); int len = in.available(); checkOidSize(len); @@ -361,6 +357,11 @@ private static ConcurrentHashMap oidTable = new ConcurrentHashMap<>(); + /** + * Returns an ObjectIdentifier instance for the specific String. + * + * If the String is not a valid OID string, an IOException is thrown. + */ public static ObjectIdentifier of(String oidStr) throws IOException { // check cache first ObjectIdentifier oid = oidTable.get(oidStr); @@ -393,8 +394,7 @@ /* * n.b. the only public interface is DerOutputStream.putOID() */ - void encode (DerOutputStream out) throws IOException - { + void encode(DerOutputStream out) throws IOException { out.write (DerValue.tag_ObjectId, encoding); } @@ -435,17 +435,21 @@ if ((encoding[i] & 0x80) == 0) { // one section [fromPos..i] if (i - fromPos + 1 > 4) { - BigInteger big = new BigInteger(1, pack(encoding, fromPos, i-fromPos+1, 7, 8)); + BigInteger big = new BigInteger(1, pack(encoding, + fromPos, i-fromPos+1, 7, 8)); if (fromPos == 0) { result[which++] = 2; - BigInteger second = big.subtract(BigInteger.valueOf(80)); - if (second.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 1) { + BigInteger second = + big.subtract(BigInteger.valueOf(80)); + if (second.compareTo( + BigInteger.valueOf(Integer.MAX_VALUE)) == 1) { return null; } else { result[which++] = second.intValue(); } } else { - if (big.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) == 1) { + if (big.compareTo( + BigInteger.valueOf(Integer.MAX_VALUE)) == 1) { return null; } else { result[which++] = big.intValue(); @@ -500,7 +504,8 @@ sb.append('.'); } if (i - fromPos + 1 > 4) { // maybe big integer - BigInteger big = new BigInteger(1, pack(encoding, fromPos, i-fromPos+1, 7, 8)); + BigInteger big = new BigInteger( + 1, pack(encoding, fromPos, i-fromPos+1, 7, 8)); if (fromPos == 0) { // first section encoded with more than 4 bytes, // must be 2.something @@ -541,7 +546,7 @@ /** * Repack all bits from input to output. On the both sides, only a portion * (from the least significant bit) of the 8 bits in a byte is used. This - * number is defined as the number of useful bits (NUB) for the array. All the + * number is defined as the number of useful bits (NUB) for the array. All * used bits from the input byte array and repacked into the output in the * exactly same order. The output bits are aligned so that the final bit of * the input (the least significant bit in the last byte), when repacked as @@ -563,7 +568,8 @@ * @param ow NUB for output * @return the repacked bytes */ - private static byte[] pack(byte[] in, int ioffset, int ilength, int iw, int ow) { + private static byte[] pack(byte[] in, + int ioffset, int ilength, int iw, int ow) { assert (iw > 0 && iw <= 8): "input NUB must be between 1 and 8"; assert (ow > 0 && ow <= 8): "output NUB must be between 1 and 8"; @@ -585,12 +591,13 @@ if (count > ow - opos%ow) { // free space available in output byte count = ow - opos%ow; // choose the smaller number } + // and move them! - out[opos/ow] |= // paste! - (((in[ioffset+ipos/iw]+256) // locate the byte (+256 so that it's never negative) - >> (iw-ipos%iw-count)) // move to the end of a byte - & ((1 << (count))-1)) // zero out all other bits - << (ow-opos%ow-count); // move to the output position + out[opos/ow] |= // paste! + (((in[ioffset+ipos/iw]+256) // locate the byte (+256 so that it's never negative) + >> (iw-ipos%iw-count)) & // move to the end of a byte + ((1 << (count))-1)) // zero out all other bits + << (ow-opos%ow-count); // move to the output position ipos += count; // advance opos += count; // advance } @@ -606,7 +613,8 @@ * @param ooffset the starting position to paste * @return the number of bytes pasted */ - private static int pack7Oid(byte[] in, int ioffset, int ilength, byte[] out, int ooffset) { + private static int pack7Oid(byte[] in, + int ioffset, int ilength, byte[] out, int ooffset) { byte[] pack = pack(in, ioffset, ilength, 8, 7); int firstNonZero = pack.length-1; // paste at least one byte for (int i=pack.length-2; i>=0; i--) { @@ -615,7 +623,8 @@ } pack[i] |= 0x80; } - System.arraycopy(pack, firstNonZero, out, ooffset, pack.length-firstNonZero); + System.arraycopy(pack, firstNonZero, + out, ooffset, pack.length-firstNonZero); return pack.length-firstNonZero; } @@ -626,7 +635,8 @@ * @param ooffset the starting position to paste * @return the number of bytes pasted */ - private static int pack8(byte[] in, int ioffset, int ilength, byte[] out, int ooffset) { + private static int pack8(byte[] in, + int ioffset, int ilength, byte[] out, int ooffset) { byte[] pack = pack(in, ioffset, ilength, 7, 8); int firstNonZero = pack.length-1; // paste at least one byte for (int i=pack.length-2; i>=0; i--) { @@ -634,7 +644,8 @@ firstNonZero = i; } } - System.arraycopy(pack, firstNonZero, out, ooffset, pack.length-firstNonZero); + System.arraycopy(pack, firstNonZero, + out, ooffset, pack.length-firstNonZero); return pack.length-firstNonZero; } @@ -686,31 +697,39 @@ } } } + private static void checkCount(int count) throws IOException { if (count < 2) { throw new IOException("ObjectIdentifier() -- " + "Must be at least two oid components "); } } + private static void checkFirstComponent(int first) throws IOException { if (first < 0 || first > 2) { throw new IOException("ObjectIdentifier() -- " + "First oid component is invalid "); } } - private static void checkFirstComponent(BigInteger first) throws IOException { + + private static void checkFirstComponent( + BigInteger first) throws IOException { if (first.signum() == -1 || first.compareTo(BigInteger.TWO) > 0) { throw new IOException("ObjectIdentifier() -- " + "First oid component is invalid "); } } - private static void checkSecondComponent(int first, int second) throws IOException { + + private static void checkSecondComponent( + int first, int second) throws IOException { if (second < 0 || first != 2 && second > 39) { throw new IOException("ObjectIdentifier() -- " + "Second oid component is invalid "); } } - private static void checkSecondComponent(int first, BigInteger second) throws IOException { + + private static void checkSecondComponent( + int first, BigInteger second) throws IOException { if (second.signum() == -1 || first != 2 && second.compareTo(BigInteger.valueOf(39)) == 1) { @@ -718,13 +737,16 @@ "Second oid component is invalid "); } } + private static void checkOtherComponent(int i, int num) throws IOException { if (num < 0) { throw new IOException("ObjectIdentifier() -- " + "oid component #" + (i+1) + " must be non-negative "); } } - private static void checkOtherComponent(int i, BigInteger num) throws IOException { + + private static void checkOtherComponent( + int i, BigInteger num) throws IOException { if (num.signum() == -1) { throw new IOException("ObjectIdentifier() -- " + "oid component #" + (i+1) + " must be non-negative "); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/util/SecurityProviderConstants.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,8 +25,11 @@ package sun.security.util; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.PatternSyntaxException; import java.security.InvalidParameterException; +import java.security.ProviderException; import javax.crypto.spec.DHParameterSpec; import sun.security.action.GetPropertyAction; @@ -35,11 +38,59 @@ * the JDK security/crypto providers. */ public final class SecurityProviderConstants { + // Cannot create one of these + private SecurityProviderConstants () {} + private static final Debug debug = Debug.getInstance("jca", "ProviderConfig"); - // Cannot create one of these - private SecurityProviderConstants () { + // cache for provider aliases; key is the standard algorithm name + // value is the associated aliases List + private static final ConcurrentHashMap> aliasesMap; + + // utility method for generating aliases list using the supplied + // 'oid' and 'extraAliases', then store into "aliasesMap" cache under the + // key 'stdName' + private static List store(String stdName, KnownOIDs oid, + String ... extraAliases) { + List value; + if (oid == null && extraAliases.length != 0) { + value = List.of(extraAliases); + } else { + value = new ArrayList<>(); + if (oid != null) { + value.add("OID." + oid.value()); + value.add(oid.value()); + String[] knownAliases = oid.aliases(); + if (knownAliases != null) { + for (String ka : knownAliases) { + value.add(ka); + } + } + } + for (String ea : extraAliases) { + value.add(ea); + } + } + aliasesMap.put(stdName, value); + return value; + } + + // returns an aliases List for the specified algorithm name o + // NOTE: exception is thrown if no aliases nor oid found, so + // only call this method if aliases are expected + public static List getAliases(String o) { + List res = aliasesMap.get(o); + if (res == null) { + KnownOIDs e = KnownOIDs.findMatch(o); + if (e != null) { + return store(o, e); + } + ProviderException pe = + new ProviderException("Cannot find aliases for " + o); + throw pe; + } + return res; } public static final int getDefDSASubprimeSize(int primeSize) { @@ -99,6 +150,7 @@ private static final String KEY_LENGTH_PROP = "jdk.security.defaultKeySize"; + static { String keyLengthStr = GetPropertyAction.privilegedGetProperty (KEY_LENGTH_PROP); @@ -169,5 +221,39 @@ DEF_RSASSA_PSS_KEY_SIZE = rsaSsaPssKeySize; DEF_DH_KEY_SIZE = dhKeySize; DEF_EC_KEY_SIZE = ecKeySize; + + // Set up aliases with default mappings + // This is needed when the mapping contains non-oid + // aliases + aliasesMap = new ConcurrentHashMap<>(); + + store("SHA1withDSA", KnownOIDs.SHA1withDSA, + KnownOIDs.OIW_JDK_SHA1withDSA.value(), + KnownOIDs.OIW_SHA1withDSA.value(), + "DSA", "SHA/DSA", "SHA-1/DSA", + "SHA1/DSA", "SHAwithDSA", "DSAWithSHA1"); + + store("DSA", KnownOIDs.DSA, KnownOIDs.OIW_DSA.value()); + + store("SHA1withRSA", KnownOIDs.SHA1withRSA, + KnownOIDs.OIW_SHA1withRSA.value()); + + store("SHA-1", KnownOIDs.SHA_1); + + store("PBEWithMD5AndDES", KnownOIDs.PBEWithMD5AndDES, "PBE"); + + store("DiffieHellman", KnownOIDs.DiffieHellman); + + store("AES", KnownOIDs.AES, "Rijndael"); + + store("EC", KnownOIDs.EC, "EllipticCurve"); + + store("X.509", null, "X509"); + store("NONEwithDSA", null, "RawDSA"); + store("DESede", null, "TripleDES"); + store("ARCFOUR", KnownOIDs.ARCFOUR); + // For backward compatility, refer to PKCS1 mapping for RSA + // KeyPairGenerator and KeyFactory + store("PKCS1", KnownOIDs.PKCS1, KnownOIDs.RSA.value()); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -28,7 +28,7 @@ import java.util.*; import java.security.cert.*; - +import sun.security.util.KnownOIDs; import sun.security.x509.NetscapeCertTypeExtension; /** @@ -71,24 +71,32 @@ private static final String OID_EXTENDED_KEY_USAGE = SimpleValidator.OID_EXTENDED_KEY_USAGE; - private static final String OID_EKU_TLS_SERVER = "1.3.6.1.5.5.7.3.1"; + private static final String OID_EKU_TLS_SERVER = + KnownOIDs.serverAuth.value(); - private static final String OID_EKU_TLS_CLIENT = "1.3.6.1.5.5.7.3.2"; + private static final String OID_EKU_TLS_CLIENT = + KnownOIDs.clientAuth.value(); - private static final String OID_EKU_CODE_SIGNING = "1.3.6.1.5.5.7.3.3"; + private static final String OID_EKU_CODE_SIGNING = + KnownOIDs.codeSigning.value(); - private static final String OID_EKU_TIME_STAMPING = "1.3.6.1.5.5.7.3.8"; + private static final String OID_EKU_TIME_STAMPING = + KnownOIDs.KP_TimeStamping.value(); - private static final String OID_EKU_ANY_USAGE = "2.5.29.37.0"; + private static final String OID_EKU_ANY_USAGE = + KnownOIDs.anyExtendedKeyUsage.value(); // the Netscape Server-Gated-Cryptography EKU extension OID - private static final String OID_EKU_NS_SGC = "2.16.840.1.113730.4.1"; + private static final String OID_EKU_NS_SGC = + KnownOIDs.NETSCAPE_ExportApproved.value(); // the Microsoft Server-Gated-Cryptography EKU extension OID - private static final String OID_EKU_MS_SGC = "1.3.6.1.4.1.311.10.3.3"; + private static final String OID_EKU_MS_SGC = + KnownOIDs.MICROSOFT_ExportApproved.value(); // the recognized extension OIDs - private static final String OID_SUBJECT_ALT_NAME = "2.5.29.17"; + private static final String OID_SUBJECT_ALT_NAME = + KnownOIDs.SubjectAlternativeName.value(); private static final String NSCT_SSL_CLIENT = NetscapeCertTypeExtension.SSL_CLIENT; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/validator/SimpleValidator.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/validator/SimpleValidator.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/validator/SimpleValidator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/validator/SimpleValidator.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -39,6 +39,7 @@ import sun.security.util.DerValue; import sun.security.util.DerInputStream; import sun.security.util.ObjectIdentifier; +import sun.security.util.KnownOIDs; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.provider.certpath.UntrustedChecker; @@ -60,24 +61,28 @@ // Constants for the OIDs we need - static final String OID_BASIC_CONSTRAINTS = "2.5.29.19"; + static final String OID_BASIC_CONSTRAINTS = + KnownOIDs.BasicConstraints.value(); - static final String OID_NETSCAPE_CERT_TYPE = "2.16.840.1.113730.1.1"; + static final String OID_NETSCAPE_CERT_TYPE = + KnownOIDs.NETSCAPE_CertType.value(); - static final String OID_KEY_USAGE = "2.5.29.15"; + static final String OID_KEY_USAGE = KnownOIDs.KeyUsage.value(); - static final String OID_EXTENDED_KEY_USAGE = "2.5.29.37"; + static final String OID_EXTENDED_KEY_USAGE = + KnownOIDs.extendedKeyUsage.value(); - static final String OID_EKU_ANY_USAGE = "2.5.29.37.0"; + static final String OID_EKU_ANY_USAGE = + KnownOIDs.anyExtendedKeyUsage.value(); static final ObjectIdentifier OBJID_NETSCAPE_CERT_TYPE = - NetscapeCertTypeExtension.NetscapeCertType_Id; + NetscapeCertTypeExtension.NetscapeCertType_Id; private static final String NSCT_SSL_CA = - NetscapeCertTypeExtension.SSL_CA; + NetscapeCertTypeExtension.SSL_CA; private static final String NSCT_CODE_SIGNING_CA = - NetscapeCertTypeExtension.OBJECT_SIGNING_CA; + NetscapeCertTypeExtension.OBJECT_SIGNING_CA; /** * The trusted certificates as: diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/AccessDescription.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/AccessDescription.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/AccessDescription.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/AccessDescription.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -42,16 +42,16 @@ private GeneralName accessLocation; public static final ObjectIdentifier Ad_OCSP_Id = - ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 1}); + ObjectIdentifier.of(KnownOIDs.OCSP); public static final ObjectIdentifier Ad_CAISSUERS_Id = - ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 2}); + ObjectIdentifier.of(KnownOIDs.caIssuers); public static final ObjectIdentifier Ad_TIMESTAMPING_Id = - ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 3}); + ObjectIdentifier.of(KnownOIDs.AD_TimeStamping); public static final ObjectIdentifier Ad_CAREPOSITORY_Id = - ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 5}); + ObjectIdentifier.of(KnownOIDs.caRepository); public AccessDescription(ObjectIdentifier accessMethod, GeneralName accessLocation) { this.accessMethod = accessMethod; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/AlgorithmId.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/AlgorithmId.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/AlgorithmId.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/AlgorithmId.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,6 +31,7 @@ import java.security.spec.MGF1ParameterSpec; import java.security.spec.PSSParameterSpec; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.security.*; import sun.security.rsa.PSSParameters; @@ -256,21 +257,31 @@ * returns the "full" signature algorithm (Ex: SHA256withECDSA) directly. */ public String getName() { - String algName = nameTable.get(algid); - if (algName != null) { - return algName; - } - if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) { - try { - AlgorithmId paramsId = + String oidStr = algid.toString(); + // first check the list of support oids + KnownOIDs o = KnownOIDs.findMatch(oidStr); + if (o == KnownOIDs.SpecifiedSHA2withECDSA) { + if (params != null) { + try { + AlgorithmId paramsId = AlgorithmId.parse(new DerValue(encodedParams)); - String paramsName = paramsId.getName(); - algName = makeSigAlg(paramsName, "EC"); - } catch (IOException e) { - // ignore + String paramsName = paramsId.getName(); + return makeSigAlg(paramsName, "EC"); + } catch (IOException e) { + // ignore + } + } + } + if (o != null) { + return o.stdName(); + } else { + String n = aliasOidsTable().get(oidStr); + if (n != null) { + return n; + } else { + return algid.toString(); } } - return (algName == null) ? algid.toString() : algName; } public AlgorithmParameters getParameters() { @@ -292,7 +303,8 @@ * @return DER encoded parameters, or null not present. */ public byte[] getEncodedParams() throws IOException { - return (encodedParams == null || algid.equals(specifiedWithECDSA_oid)) + return (encodedParams == null || + algid.toString().equals(KnownOIDs.SpecifiedSHA2withECDSA.value())) ? null : encodedParams.clone(); } @@ -488,541 +500,142 @@ * used as a "KeyPairGenerator" algorithm. */ private static ObjectIdentifier algOID(String name) throws IOException { - // See if algname is in printable OID ("dot-dot") notation - if (name.indexOf('.') != -1) { - if (name.startsWith("OID.")) { - return new ObjectIdentifier(name.substring("OID.".length())); - } else { - return new ObjectIdentifier(name); - } - } - - // Digesting algorithms - if (name.equalsIgnoreCase("MD5")) { - return AlgorithmId.MD5_oid; - } - if (name.equalsIgnoreCase("MD2")) { - return AlgorithmId.MD2_oid; - } - if (name.equalsIgnoreCase("SHA") || name.equalsIgnoreCase("SHA1") - || name.equalsIgnoreCase("SHA-1")) { - return AlgorithmId.SHA_oid; - } - if (name.equalsIgnoreCase("SHA-256") || - name.equalsIgnoreCase("SHA256")) { - return AlgorithmId.SHA256_oid; - } - if (name.equalsIgnoreCase("SHA-384") || - name.equalsIgnoreCase("SHA384")) { - return AlgorithmId.SHA384_oid; - } - if (name.equalsIgnoreCase("SHA-512") || - name.equalsIgnoreCase("SHA512")) { - return AlgorithmId.SHA512_oid; - } - if (name.equalsIgnoreCase("SHA-224") || - name.equalsIgnoreCase("SHA224")) { - return AlgorithmId.SHA224_oid; - } - if (name.equalsIgnoreCase("SHA-512/224") || - name.equalsIgnoreCase("SHA512/224")) { - return AlgorithmId.SHA512_224_oid; - } - if (name.equalsIgnoreCase("SHA-512/256") || - name.equalsIgnoreCase("SHA512/256")) { - return AlgorithmId.SHA512_256_oid; - } - // Various public key algorithms - if (name.equalsIgnoreCase("RSA")) { - return AlgorithmId.RSAEncryption_oid; - } - if (name.equalsIgnoreCase("RSASSA-PSS")) { - return AlgorithmId.RSASSA_PSS_oid; - } - if (name.equalsIgnoreCase("RSAES-OAEP")) { - return AlgorithmId.RSAES_OAEP_oid; - } - if (name.equalsIgnoreCase("Diffie-Hellman") - || name.equalsIgnoreCase("DH")) { - return AlgorithmId.DH_oid; - } - if (name.equalsIgnoreCase("DSA")) { - return AlgorithmId.DSA_oid; - } - if (name.equalsIgnoreCase("EC")) { - return EC_oid; - } - if (name.equalsIgnoreCase("ECDH")) { - return AlgorithmId.ECDH_oid; - } - - // Secret key algorithms - if (name.equalsIgnoreCase("AES")) { - return AlgorithmId.AES_oid; + if (name.startsWith("OID.")) { + name = name.substring("OID.".length()); } - // Common signature types - if (name.equalsIgnoreCase("MD5withRSA") - || name.equalsIgnoreCase("MD5/RSA")) { - return AlgorithmId.md5WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("MD2withRSA") - || name.equalsIgnoreCase("MD2/RSA")) { - return AlgorithmId.md2WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHAwithDSA") - || name.equalsIgnoreCase("SHA1withDSA") - || name.equalsIgnoreCase("SHA/DSA") - || name.equalsIgnoreCase("SHA1/DSA") - || name.equalsIgnoreCase("DSAWithSHA1") - || name.equalsIgnoreCase("DSS") - || name.equalsIgnoreCase("SHA-1/DSA")) { - return AlgorithmId.sha1WithDSA_oid; - } - if (name.equalsIgnoreCase("SHA224WithDSA")) { - return AlgorithmId.sha224WithDSA_oid; - } - if (name.equalsIgnoreCase("SHA256WithDSA")) { - return AlgorithmId.sha256WithDSA_oid; - } - if (name.equalsIgnoreCase("SHA1WithRSA") - || name.equalsIgnoreCase("SHA1/RSA")) { - return AlgorithmId.sha1WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHA256WithRSA")) { - return AlgorithmId.sha256WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHA384WithRSA")) { - return AlgorithmId.sha384WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHA512WithRSA")) { - return AlgorithmId.sha512WithRSAEncryption_oid; - } - if (name.equalsIgnoreCase("SHA1withECDSA") - || name.equalsIgnoreCase("ECDSA")) { - return AlgorithmId.sha1WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA224withECDSA")) { - return AlgorithmId.sha224WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA256withECDSA")) { - return AlgorithmId.sha256WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA384withECDSA")) { - return AlgorithmId.sha384WithECDSA_oid; - } - if (name.equalsIgnoreCase("SHA512withECDSA")) { - return AlgorithmId.sha512WithECDSA_oid; + KnownOIDs k = KnownOIDs.findMatch(name); + if (k != null) { + return ObjectIdentifier.of(k); + } + + // unknown algorithm oids + if (name.indexOf(".") == -1) { + // see if there is a matching oid string alias mapping from + // 3rd party providers + name = name.toUpperCase(Locale.ENGLISH); + String oidStr = aliasOidsTable().get(name); + if (oidStr != null) { + return ObjectIdentifier.of(oidStr); + } return null; + } else { + return ObjectIdentifier.of(name); } - - return oidTable().get(name.toUpperCase(Locale.ENGLISH)); - } - - private static ObjectIdentifier oid(int ... values) { - return ObjectIdentifier.newInternal(values); } - private static volatile Map oidTable; - private static final Map nameTable; + // oid string cache index'ed by algorithm name and oid strings + private static volatile Map aliasOidsTable; - /** Returns the oidTable, lazily initializing it on first access. */ - private static Map oidTable() - throws IOException { - // Double checked locking; safe because oidTable is volatile - Map tab; - if ((tab = oidTable) == null) { + // returns the aliasOidsTable, lazily initializing it on first access. + private static Map aliasOidsTable() { + // Double checked locking; safe because aliasOidsTable is volatile + Map tab = aliasOidsTable; + if (tab == null) { synchronized (AlgorithmId.class) { - if ((tab = oidTable) == null) - oidTable = tab = computeOidTable(); + if ((tab = aliasOidsTable) == null) { + aliasOidsTable = tab = collectOIDAliases(); + } } } return tab; } - /** Collects the algorithm names from the installed providers. */ - private static HashMap computeOidTable() - throws IOException { - HashMap tab = new HashMap<>(); + private static boolean isKnownProvider(Provider p) { + String pn = p.getName(); + String mn = p.getClass().getModule().getName(); + if (pn != null && mn != null) { + return ((mn.equals("java.base") && + (pn.equals("SUN") || pn.equals("SunRsaSign") || + pn.equals("SunJCE") || pn.equals("SunJSSE"))) || + (mn.equals("jdk.crypto.ec") && pn.equals("SunEC")) || + (mn.equals("jdk.crypto.mscapi") && pn.equals("SunMSCAPI")) || + (mn.equals("jdk.crypto.cryptoki") && + pn.startsWith("SunPKCS11"))); + } else { + return false; + } + } + + private static ConcurrentHashMap collectOIDAliases() { + ConcurrentHashMap t = new ConcurrentHashMap<>(); for (Provider provider : Security.getProviders()) { + // skip providers which are already using SecurityProviderConstants + // and KnownOIDs + if (isKnownProvider(provider)) { + continue; + } for (Object key : provider.keySet()) { String alias = (String)key; String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); int index; if (upperCaseAlias.startsWith("ALG.ALIAS") && - (index=upperCaseAlias.indexOf("OID.", 0)) != -1) { + (index = upperCaseAlias.indexOf("OID.", 0)) != -1) { index += "OID.".length(); if (index == alias.length()) { // invalid alias entry break; } - String oidString = alias.substring(index); + String ostr = alias.substring(index); String stdAlgName = provider.getProperty(alias); if (stdAlgName != null) { stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); } - if (stdAlgName != null && - tab.get(stdAlgName) == null) { - tab.put(stdAlgName, new ObjectIdentifier(oidString)); + // add the name->oid and oid->name mappings if none exists + if (KnownOIDs.findMatch(stdAlgName) == null) { + // not override earlier entries if it exists + t.putIfAbsent(stdAlgName, ostr); + } + if (KnownOIDs.findMatch(ostr) == null) { + // not override earlier entries if it exists + t.putIfAbsent(ostr, stdAlgName); } } } } - return tab; + return t; } - /*****************************************************************/ - - /* - * HASHING ALGORITHMS - */ - - /** - * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319. - * OID = 1.2.840.113549.2.2 - */ public static final ObjectIdentifier MD2_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 2}); + ObjectIdentifier.of(KnownOIDs.MD2); - /** - * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321. - * OID = 1.2.840.113549.2.5 - */ public static final ObjectIdentifier MD5_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 5}); + ObjectIdentifier.of(KnownOIDs.MD5); - /** - * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1. - * This is sometimes called "SHA", though that is often confusing since - * many people refer to FIPS 180 (which has an error) as defining SHA. - * OID = 1.3.14.3.2.26. Old SHA-0 OID: 1.3.14.3.2.18. - */ public static final ObjectIdentifier SHA_oid = - ObjectIdentifier.newInternal(new int[] {1, 3, 14, 3, 2, 26}); + ObjectIdentifier.of(KnownOIDs.SHA_1); public static final ObjectIdentifier SHA224_oid = - ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 4}); + ObjectIdentifier.of(KnownOIDs.SHA_224); public static final ObjectIdentifier SHA256_oid = - ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 1}); + ObjectIdentifier.of(KnownOIDs.SHA_256); public static final ObjectIdentifier SHA384_oid = - ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 2}); + ObjectIdentifier.of(KnownOIDs.SHA_384); public static final ObjectIdentifier SHA512_oid = - ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3}); + ObjectIdentifier.of(KnownOIDs.SHA_512); public static final ObjectIdentifier SHA512_224_oid = - ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 5}); + ObjectIdentifier.of(KnownOIDs.SHA_512$224); public static final ObjectIdentifier SHA512_256_oid = - ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 6}); + ObjectIdentifier.of(KnownOIDs.SHA_512$256); - /* - * COMMON PUBLIC KEY TYPES - */ - private static final int[] DH_data = { 1, 2, 840, 113549, 1, 3, 1 }; - private static final int[] DH_PKIX_data = { 1, 2, 840, 10046, 2, 1 }; - private static final int[] DSA_OIW_data = { 1, 3, 14, 3, 2, 12 }; - private static final int[] DSA_PKIX_data = { 1, 2, 840, 10040, 4, 1 }; - private static final int[] RSA_data = { 2, 5, 8, 1, 1 }; - - public static final ObjectIdentifier DH_oid; - public static final ObjectIdentifier DH_PKIX_oid; - public static final ObjectIdentifier DSA_oid; - public static final ObjectIdentifier DSA_OIW_oid; - public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1); - public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12); - public static final ObjectIdentifier RSA_oid; - public static final ObjectIdentifier RSAEncryption_oid = - oid(1, 2, 840, 113549, 1, 1, 1); - public static final ObjectIdentifier RSAES_OAEP_oid = - oid(1, 2, 840, 113549, 1, 1, 7); - public static final ObjectIdentifier mgf1_oid = - oid(1, 2, 840, 113549, 1, 1, 8); - public static final ObjectIdentifier RSASSA_PSS_oid = - oid(1, 2, 840, 113549, 1, 1, 10); - - /* - * COMMON SECRET KEY TYPES - */ - public static final ObjectIdentifier AES_oid = - oid(2, 16, 840, 1, 101, 3, 4, 1); - - /* - * COMMON SIGNATURE ALGORITHMS - */ - private static final int[] md2WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 2 }; - private static final int[] md5WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 4 }; - private static final int[] sha1WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 5 }; - private static final int[] sha1WithRSAEncryption_OIW_data = - { 1, 3, 14, 3, 2, 29 }; - private static final int[] sha224WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 14 }; - private static final int[] sha256WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 11 }; - private static final int[] sha384WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 12 }; - private static final int[] sha512WithRSAEncryption_data = - { 1, 2, 840, 113549, 1, 1, 13 }; - - private static final int[] shaWithDSA_OIW_data = - { 1, 3, 14, 3, 2, 13 }; - private static final int[] sha1WithDSA_OIW_data = - { 1, 3, 14, 3, 2, 27 }; - private static final int[] dsaWithSHA1_PKIX_data = - { 1, 2, 840, 10040, 4, 3 }; - - public static final ObjectIdentifier md2WithRSAEncryption_oid; - public static final ObjectIdentifier md5WithRSAEncryption_oid; - public static final ObjectIdentifier sha1WithRSAEncryption_oid; - public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid; - public static final ObjectIdentifier sha224WithRSAEncryption_oid; - public static final ObjectIdentifier sha256WithRSAEncryption_oid; - public static final ObjectIdentifier sha384WithRSAEncryption_oid; - public static final ObjectIdentifier sha512WithRSAEncryption_oid; - public static final ObjectIdentifier sha512_224WithRSAEncryption_oid = - oid(1, 2, 840, 113549, 1, 1, 15); - public static final ObjectIdentifier sha512_256WithRSAEncryption_oid = - oid(1, 2, 840, 113549, 1, 1, 16);; - - public static final ObjectIdentifier shaWithDSA_OIW_oid; - public static final ObjectIdentifier sha1WithDSA_OIW_oid; - public static final ObjectIdentifier sha1WithDSA_oid; - public static final ObjectIdentifier sha224WithDSA_oid = - oid(2, 16, 840, 1, 101, 3, 4, 3, 1); - public static final ObjectIdentifier sha256WithDSA_oid = - oid(2, 16, 840, 1, 101, 3, 4, 3, 2); - - public static final ObjectIdentifier sha1WithECDSA_oid = - oid(1, 2, 840, 10045, 4, 1); - public static final ObjectIdentifier sha224WithECDSA_oid = - oid(1, 2, 840, 10045, 4, 3, 1); - public static final ObjectIdentifier sha256WithECDSA_oid = - oid(1, 2, 840, 10045, 4, 3, 2); - public static final ObjectIdentifier sha384WithECDSA_oid = - oid(1, 2, 840, 10045, 4, 3, 3); - public static final ObjectIdentifier sha512WithECDSA_oid = - oid(1, 2, 840, 10045, 4, 3, 4); - public static final ObjectIdentifier specifiedWithECDSA_oid = - oid(1, 2, 840, 10045, 4, 3); - - /** - * Algorithm ID for the PBE encryption algorithms from PKCS#5 and - * PKCS#12. - */ - public static final ObjectIdentifier pbeWithMD5AndDES_oid = - ObjectIdentifier.newInternal(new int[]{1, 2, 840, 113549, 1, 5, 3}); - public static final ObjectIdentifier pbeWithMD5AndRC2_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 6}); - public static final ObjectIdentifier pbeWithSHA1AndDES_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 10}); - public static final ObjectIdentifier pbeWithSHA1AndRC2_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 11}); - public static ObjectIdentifier pbeWithSHA1AndRC4_128_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 1}); - public static ObjectIdentifier pbeWithSHA1AndRC4_40_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 2}); - public static ObjectIdentifier pbeWithSHA1AndDESede_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 3}); - public static ObjectIdentifier pbeWithSHA1AndRC2_128_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 5}); - public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid = - ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6}); - - static { - /* - * Note the preferred OIDs are named simply with no "OIW" or - * "PKIX" in them, even though they may point to data from these - * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid... - */ - /** - * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3. - * Parameters include public values P and G, and may optionally specify - * the length of the private key X. Alternatively, algorithm parameters - * may be derived from another source such as a Certificate Authority's - * certificate. - * OID = 1.2.840.113549.1.3.1 - */ - DH_oid = ObjectIdentifier.newInternal(DH_data); - - /** - * Algorithm ID for the Diffie Hellman Key Agreement (DH), from RFC 3279. - * Parameters may include public values P and G. - * OID = 1.2.840.10046.2.1 - */ - DH_PKIX_oid = ObjectIdentifier.newInternal(DH_PKIX_data); - - /** - * Algorithm ID for the Digital Signing Algorithm (DSA), from the - * NIST OIW Stable Agreements part 12. - * Parameters may include public values P, Q, and G; or these may be - * derived from - * another source such as a Certificate Authority's certificate. - * OID = 1.3.14.3.2.12 - */ - DSA_OIW_oid = ObjectIdentifier.newInternal(DSA_OIW_data); - - /** - * Algorithm ID for the Digital Signing Algorithm (DSA), from RFC 3279. - * Parameters may include public values P, Q, and G; or these may be - * derived from another source such as a Certificate Authority's - * certificate. - * OID = 1.2.840.10040.4.1 - */ - DSA_oid = ObjectIdentifier.newInternal(DSA_PKIX_data); + public static final ObjectIdentifier DSA_oid = + ObjectIdentifier.of(KnownOIDs.DSA); - /** - * Algorithm ID for RSA keys used for any purpose, as defined in X.509. - * The algorithm parameter is a single value, the number of bits in the - * public modulus. - * OID = 2.5.8.1.1 - */ - RSA_oid = ObjectIdentifier.newInternal(RSA_data); - - /** - * Identifies a signing algorithm where an MD2 digest is encrypted - * using an RSA private key; defined in PKCS #1. Use of this - * signing algorithm is discouraged due to MD2 vulnerabilities. - * OID = 1.2.840.113549.1.1.2 - */ - md2WithRSAEncryption_oid = - ObjectIdentifier.newInternal(md2WithRSAEncryption_data); - - /** - * Identifies a signing algorithm where an MD5 digest is - * encrypted using an RSA private key; defined in PKCS #1. - * OID = 1.2.840.113549.1.1.4 - */ - md5WithRSAEncryption_oid = - ObjectIdentifier.newInternal(md5WithRSAEncryption_data); + public static final ObjectIdentifier EC_oid = + ObjectIdentifier.of(KnownOIDs.EC); - /** - * Identifies a signing algorithm where a SHA1 digest is - * encrypted using an RSA private key; defined by RSA DSI. - * OID = 1.2.840.113549.1.1.5 - */ - sha1WithRSAEncryption_oid = - ObjectIdentifier.newInternal(sha1WithRSAEncryption_data); - - /** - * Identifies a signing algorithm where a SHA1 digest is - * encrypted using an RSA private key; defined in NIST OIW. - * OID = 1.3.14.3.2.29 - */ - sha1WithRSAEncryption_OIW_oid = - ObjectIdentifier.newInternal(sha1WithRSAEncryption_OIW_data); - - /** - * Identifies a signing algorithm where a SHA224 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.14 - */ - sha224WithRSAEncryption_oid = - ObjectIdentifier.newInternal(sha224WithRSAEncryption_data); - - /** - * Identifies a signing algorithm where a SHA256 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.11 - */ - sha256WithRSAEncryption_oid = - ObjectIdentifier.newInternal(sha256WithRSAEncryption_data); - - /** - * Identifies a signing algorithm where a SHA384 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.12 - */ - sha384WithRSAEncryption_oid = - ObjectIdentifier.newInternal(sha384WithRSAEncryption_data); - - /** - * Identifies a signing algorithm where a SHA512 digest is - * encrypted using an RSA private key; defined by PKCS #1. - * OID = 1.2.840.113549.1.1.13 - */ - sha512WithRSAEncryption_oid = - ObjectIdentifier.newInternal(sha512WithRSAEncryption_data); - - /** - * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a - * SHA digest is signed using the Digital Signing Algorithm (DSA). - * This should not be used. - * OID = 1.3.14.3.2.13 - */ - shaWithDSA_OIW_oid = ObjectIdentifier.newInternal(shaWithDSA_OIW_data); - - /** - * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a - * SHA1 digest is signed using the Digital Signing Algorithm (DSA). - * OID = 1.3.14.3.2.27 - */ - sha1WithDSA_OIW_oid = ObjectIdentifier.newInternal(sha1WithDSA_OIW_data); - - /** - * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a - * SHA1 digest is signed using the Digital Signing Algorithm (DSA). - * OID = 1.2.840.10040.4.3 - */ - sha1WithDSA_oid = ObjectIdentifier.newInternal(dsaWithSHA1_PKIX_data); - - nameTable = new HashMap<>(); - nameTable.put(MD5_oid, "MD5"); - nameTable.put(MD2_oid, "MD2"); - nameTable.put(SHA_oid, "SHA-1"); - nameTable.put(SHA224_oid, "SHA-224"); - nameTable.put(SHA256_oid, "SHA-256"); - nameTable.put(SHA384_oid, "SHA-384"); - nameTable.put(SHA512_oid, "SHA-512"); - nameTable.put(SHA512_224_oid, "SHA-512/224"); - nameTable.put(SHA512_256_oid, "SHA-512/256"); - nameTable.put(RSAEncryption_oid, "RSA"); - nameTable.put(RSA_oid, "RSA"); - nameTable.put(DH_oid, "Diffie-Hellman"); - nameTable.put(DH_PKIX_oid, "Diffie-Hellman"); - nameTable.put(DSA_oid, "DSA"); - nameTable.put(DSA_OIW_oid, "DSA"); - nameTable.put(EC_oid, "EC"); - nameTable.put(ECDH_oid, "ECDH"); - - nameTable.put(AES_oid, "AES"); + public static final ObjectIdentifier RSAEncryption_oid = + ObjectIdentifier.of(KnownOIDs.RSA); - nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA"); - nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA"); - nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA"); - nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA"); - nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA"); - nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA"); - nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA"); - nameTable.put(sha1WithDSA_oid, "SHA1withDSA"); - nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA"); - nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA"); - nameTable.put(sha224WithDSA_oid, "SHA224withDSA"); - nameTable.put(sha256WithDSA_oid, "SHA256withDSA"); - nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA"); - nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA"); - nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA"); - nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA"); - nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA"); - nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA"); - nameTable.put(sha512_224WithRSAEncryption_oid, "SHA512/224withRSA"); - nameTable.put(sha512_256WithRSAEncryption_oid, "SHA512/256withRSA"); - nameTable.put(RSASSA_PSS_oid, "RSASSA-PSS"); - nameTable.put(RSAES_OAEP_oid, "RSAES-OAEP"); + public static final ObjectIdentifier RSASSA_PSS_oid = + ObjectIdentifier.of(KnownOIDs.RSASSA_PSS); - nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES"); - nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2"); - nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES"); - nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2"); - nameTable.put(pbeWithSHA1AndRC4_128_oid, "PBEWithSHA1AndRC4_128"); - nameTable.put(pbeWithSHA1AndRC4_40_oid, "PBEWithSHA1AndRC4_40"); - nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede"); - nameTable.put(pbeWithSHA1AndRC2_128_oid, "PBEWithSHA1AndRC2_128"); - nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40"); - } + public static final ObjectIdentifier MGF1_oid = + ObjectIdentifier.of(KnownOIDs.MGF1); /** * Creates a signature algorithm name from a digest algorithm diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/AVA.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/AVA.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/AVA.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/AVA.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1237,7 +1237,7 @@ return ak.oid; } } else { - return new ObjectIdentifier(oidString); + return ObjectIdentifier.of(oidString); } // no keyword found, check if OID string @@ -1255,7 +1255,7 @@ if (number == false) { throw new IOException("Invalid keyword \"" + keyword + "\""); } - return new ObjectIdentifier(keyword); + return ObjectIdentifier.of(keyword); } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/ExtendedKeyUsageExtension.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -34,9 +34,7 @@ import java.util.Map; import java.util.Vector; -import sun.security.util.DerValue; -import sun.security.util.DerOutputStream; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; /** * This class defines the Extended Key Usage Extension, which @@ -94,35 +92,6 @@ public static final String NAME = "ExtendedKeyUsage"; public static final String USAGES = "usages"; - // OID defined in RFC 5280 Sections 4.2.1.12 - // more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html - private static final Map map = - new HashMap (); - - private static final int[] anyExtendedKeyUsageOidData = {2, 5, 29, 37, 0}; - private static final int[] serverAuthOidData = {1, 3, 6, 1, 5, 5, 7, 3, 1}; - private static final int[] clientAuthOidData = {1, 3, 6, 1, 5, 5, 7, 3, 2}; - private static final int[] codeSigningOidData = {1, 3, 6, 1, 5, 5, 7, 3, 3}; - private static final int[] emailProtectionOidData = {1, 3, 6, 1, 5, 5, 7, 3, 4}; - private static final int[] ipsecEndSystemOidData = {1, 3, 6, 1, 5, 5, 7, 3, 5}; - private static final int[] ipsecTunnelOidData = {1, 3, 6, 1, 5, 5, 7, 3, 6}; - private static final int[] ipsecUserOidData = {1, 3, 6, 1, 5, 5, 7, 3, 7}; - private static final int[] timeStampingOidData = {1, 3, 6, 1, 5, 5, 7, 3, 8}; - private static final int[] OCSPSigningOidData = {1, 3, 6, 1, 5, 5, 7, 3, 9}; - - static { - map.put(ObjectIdentifier.newInternal(anyExtendedKeyUsageOidData), "anyExtendedKeyUsage"); - map.put(ObjectIdentifier.newInternal(serverAuthOidData), "serverAuth"); - map.put(ObjectIdentifier.newInternal(clientAuthOidData), "clientAuth"); - map.put(ObjectIdentifier.newInternal(codeSigningOidData), "codeSigning"); - map.put(ObjectIdentifier.newInternal(emailProtectionOidData), "emailProtection"); - map.put(ObjectIdentifier.newInternal(ipsecEndSystemOidData), "ipsecEndSystem"); - map.put(ObjectIdentifier.newInternal(ipsecTunnelOidData), "ipsecTunnel"); - map.put(ObjectIdentifier.newInternal(ipsecUserOidData), "ipsecUser"); - map.put(ObjectIdentifier.newInternal(timeStampingOidData), "timeStamping"); - map.put(ObjectIdentifier.newInternal(OCSPSigningOidData), "OCSPSigning"); - }; - /** * Vector of KeyUsages for this object. */ @@ -209,11 +178,12 @@ usage += "\n "; } - String result = map.get(oid); - if (result != null) { - usage += result; + String res = oid.toString(); + KnownOIDs os = KnownOIDs.findMatch(res); + if (os != null) { + usage += os.stdName(); } else { - usage += oid.toString(); + usage += res; } first = false; } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/GeneralSubtrees.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -270,8 +270,7 @@ newName = new GeneralName(new IPAddressName((byte[])null)); break; case GeneralNameInterface.NAME_OID: - newName = new GeneralName - (new OIDName(new ObjectIdentifier((int[])null))); + newName = new GeneralName(new OIDName("")); break; default: throw new IOException diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/InhibitAnyPolicyExtension.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -29,10 +29,7 @@ import java.io.OutputStream; import java.util.Enumeration; -import sun.security.util.Debug; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; /** * This class represents the Inhibit Any-Policy Extension. @@ -75,14 +72,8 @@ /** * Object identifier for "any-policy" */ - public static ObjectIdentifier AnyPolicy_Id; - static { - try { - AnyPolicy_Id = new ObjectIdentifier("2.5.29.32.0"); - } catch (IOException ioe) { - // Should not happen - } - } + public static ObjectIdentifier AnyPolicy_Id = + ObjectIdentifier.of(KnownOIDs.CE_CERT_POLICIES_ANY); /** * Attribute names. diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/NetscapeCertTypeExtension.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -69,20 +69,11 @@ public static final String S_MIME_CA = "s_mime_ca"; public static final String OBJECT_SIGNING_CA = "object_signing_ca"; - private static final int[] CertType_data = { 2, 16, 840, 1, 113730, 1, 1 }; - /** * Object identifier for the Netscape-Cert-Type extension. */ - public static ObjectIdentifier NetscapeCertType_Id; - - static { - try { - NetscapeCertType_Id = new ObjectIdentifier(CertType_data); - } catch (IOException ioe) { - // should not happen - } - } + public static ObjectIdentifier NetscapeCertType_Id = + ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertType); private boolean[] bitString; diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/OIDMap.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/OIDMap.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/OIDMap.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/OIDMap.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -102,9 +102,6 @@ private static final String OCSPNOCHECK = ROOT + "." + OCSPNoCheckExtension.NAME; - private static final int[] NetscapeCertType_data = - { 2, 16, 840, 1, 113730, 1, 1 }; - /** Map ObjectIdentifier(oid) -> OIDInfo(info) */ private static final Map oidMap; @@ -138,8 +135,8 @@ "sun.security.x509.AuthorityKeyIdentifierExtension"); addInternal(POLICY_CONSTRAINTS, PKIXExtensions.PolicyConstraints_Id, "sun.security.x509.PolicyConstraintsExtension"); - addInternal(NETSCAPE_CERT, ObjectIdentifier.newInternal - (new int[] {2,16,840,1,113730,1,1}), + addInternal(NETSCAPE_CERT, + ObjectIdentifier.of(KnownOIDs.NETSCAPE_CertType), "sun.security.x509.NetscapeCertTypeExtension"); addInternal(CERT_POLICIES, PKIXExtensions.CertificatePolicies_Id, "sun.security.x509.CertificatePoliciesExtension"); @@ -230,7 +227,7 @@ throws CertificateException { ObjectIdentifier objId; try { - objId = new ObjectIdentifier(oid); + objId = ObjectIdentifier.of(oid); } catch (IOException ioe) { throw new CertificateException ("Invalid Object identifier: " + oid); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/OIDName.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/OIDName.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/OIDName.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/OIDName.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -69,7 +69,7 @@ */ public OIDName(String name) throws IOException { try { - oid = new ObjectIdentifier(name); + oid = ObjectIdentifier.of(name); } catch (Exception e) { throw new IOException("Unable to create OIDName: " + e); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/PKIXExtensions.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,6 @@ package sun.security.x509; -import java.io.*; import sun.security.util.*; @@ -48,163 +47,151 @@ * @author Hemma Prafullchandra */ public class PKIXExtensions { - // The object identifiers - private static final int[] AuthorityKey_data = { 2, 5, 29, 35 }; - private static final int[] SubjectKey_data = { 2, 5, 29, 14 }; - private static final int[] KeyUsage_data = { 2, 5, 29, 15 }; - private static final int[] PrivateKeyUsage_data = { 2, 5, 29, 16 }; - private static final int[] CertificatePolicies_data = { 2, 5, 29, 32 }; - private static final int[] PolicyMappings_data = { 2, 5, 29, 33 }; - private static final int[] SubjectAlternativeName_data = { 2, 5, 29, 17 }; - private static final int[] IssuerAlternativeName_data = { 2, 5, 29, 18 }; - private static final int[] SubjectDirectoryAttributes_data = { 2, 5, 29, 9 }; - private static final int[] BasicConstraints_data = { 2, 5, 29, 19 }; - private static final int[] NameConstraints_data = { 2, 5, 29, 30 }; - private static final int[] PolicyConstraints_data = { 2, 5, 29, 36 }; - private static final int[] CRLDistributionPoints_data = { 2, 5, 29, 31 }; - private static final int[] CRLNumber_data = { 2, 5, 29, 20 }; - private static final int[] IssuingDistributionPoint_data = { 2, 5, 29, 28 }; - private static final int[] DeltaCRLIndicator_data = { 2, 5, 29, 27 }; - private static final int[] ReasonCode_data = { 2, 5, 29, 21 }; - private static final int[] HoldInstructionCode_data = { 2, 5, 29, 23 }; - private static final int[] InvalidityDate_data = { 2, 5, 29, 24 }; - private static final int[] ExtendedKeyUsage_data = { 2, 5, 29, 37 }; - private static final int[] InhibitAnyPolicy_data = { 2, 5, 29, 54 }; - private static final int[] CertificateIssuer_data = { 2, 5, 29, 29 }; - private static final int[] AuthInfoAccess_data = { 1, 3, 6, 1, 5, 5, 7, 1, 1}; - private static final int[] SubjectInfoAccess_data = { 1, 3, 6, 1, 5, 5, 7, 1, 11}; - private static final int[] FreshestCRL_data = { 2, 5, 29, 46 }; - private static final int[] OCSPNoCheck_data = { 1, 3, 6, 1, 5, 5, 7, - 48, 1, 5}; - - // Additional extensions under the PKIX arc that are not necessarily - // used in X.509 Certificates or CRLs. - private static final int OCSPNonce_data [] = { 1, 3, 6, 1, 5, 5, 7, - 48, 1, 2}; - /** * Identifies the particular public key used to sign the certificate. */ - public static final ObjectIdentifier AuthorityKey_Id; + public static final ObjectIdentifier AuthorityKey_Id = + ObjectIdentifier.of(KnownOIDs.AuthorityKeyID); /** * Identifies the particular public key used in an application. */ - public static final ObjectIdentifier SubjectKey_Id; + public static final ObjectIdentifier SubjectKey_Id = + ObjectIdentifier.of(KnownOIDs.SubjectKeyID); /** * Defines the purpose of the key contained in the certificate. */ - public static final ObjectIdentifier KeyUsage_Id; + public static final ObjectIdentifier KeyUsage_Id = + ObjectIdentifier.of(KnownOIDs.KeyUsage); /** * Allows the certificate issuer to specify a different validity period * for the private key than the certificate. */ - public static final ObjectIdentifier PrivateKeyUsage_Id; + public static final ObjectIdentifier PrivateKeyUsage_Id = + ObjectIdentifier.of(KnownOIDs.PrivateKeyUsage); /** * Contains the sequence of policy information terms. */ - public static final ObjectIdentifier CertificatePolicies_Id; + public static final ObjectIdentifier CertificatePolicies_Id = + ObjectIdentifier.of(KnownOIDs.CertificatePolicies); /** * Lists pairs of object identifiers of policies considered equivalent by * the issuing CA to the subject CA. */ - public static final ObjectIdentifier PolicyMappings_Id; + public static final ObjectIdentifier PolicyMappings_Id = + ObjectIdentifier.of(KnownOIDs.PolicyMappings); /** * Allows additional identities to be bound to the subject of the * certificate. */ - public static final ObjectIdentifier SubjectAlternativeName_Id; + public static final ObjectIdentifier SubjectAlternativeName_Id = + ObjectIdentifier.of(KnownOIDs.SubjectAlternativeName); /** * Allows additional identities to be associated with the certificate * issuer. */ - public static final ObjectIdentifier IssuerAlternativeName_Id; + public static final ObjectIdentifier IssuerAlternativeName_Id = + ObjectIdentifier.of(KnownOIDs.IssuerAlternativeName); /** * Identifies additional directory attributes. * This extension is always non-critical. */ - public static final ObjectIdentifier SubjectDirectoryAttributes_Id; + public static final ObjectIdentifier SubjectDirectoryAttributes_Id = + ObjectIdentifier.of(KnownOIDs.SubjectDirectoryAttributes); /** * Identifies whether the subject of the certificate is a CA and how deep * a certification path may exist through that CA. */ - public static final ObjectIdentifier BasicConstraints_Id; + public static final ObjectIdentifier BasicConstraints_Id = + ObjectIdentifier.of(KnownOIDs.BasicConstraints); /** * Provides for permitted and excluded subtrees that place restrictions * on names that may be included within a certificate issued by a given CA. */ - public static final ObjectIdentifier NameConstraints_Id; + public static final ObjectIdentifier NameConstraints_Id = + ObjectIdentifier.of(KnownOIDs.NameConstraints); /** * Used to either prohibit policy mapping or limit the set of policies * that can be in subsequent certificates. */ - public static final ObjectIdentifier PolicyConstraints_Id; + public static final ObjectIdentifier PolicyConstraints_Id = + ObjectIdentifier.of(KnownOIDs.PolicyConstraints); /** * Identifies how CRL information is obtained. */ - public static final ObjectIdentifier CRLDistributionPoints_Id; + public static final ObjectIdentifier CRLDistributionPoints_Id = + ObjectIdentifier.of(KnownOIDs.CRLDistributionPoints); /** * Conveys a monotonically increasing sequence number for each CRL * issued by a given CA. */ - public static final ObjectIdentifier CRLNumber_Id; + public static final ObjectIdentifier CRLNumber_Id = + ObjectIdentifier.of(KnownOIDs.CRLNumber); /** * Identifies the CRL distribution point for a particular CRL. */ - public static final ObjectIdentifier IssuingDistributionPoint_Id; + public static final ObjectIdentifier IssuingDistributionPoint_Id = + ObjectIdentifier.of(KnownOIDs.IssuingDistributionPoint); /** * Identifies the delta CRL. */ - public static final ObjectIdentifier DeltaCRLIndicator_Id; + public static final ObjectIdentifier DeltaCRLIndicator_Id = + ObjectIdentifier.of(KnownOIDs.DeltaCRLIndicator); /** * Identifies the reason for the certificate revocation. */ - public static final ObjectIdentifier ReasonCode_Id; + public static final ObjectIdentifier ReasonCode_Id = + ObjectIdentifier.of(KnownOIDs.ReasonCode); /** * This extension provides a registered instruction identifier indicating * the action to be taken, after encountering a certificate that has been * placed on hold. */ - public static final ObjectIdentifier HoldInstructionCode_Id; + public static final ObjectIdentifier HoldInstructionCode_Id = + ObjectIdentifier.of(KnownOIDs.HoldInstructionCode); /** * Identifies the date on which it is known or suspected that the private * key was compromised or that the certificate otherwise became invalid. */ - public static final ObjectIdentifier InvalidityDate_Id; + public static final ObjectIdentifier InvalidityDate_Id = + ObjectIdentifier.of(KnownOIDs.InvalidityDate); /** * Identifies one or more purposes for which the certified public key * may be used, in addition to or in place of the basic purposes * indicated in the key usage extension field. */ - public static final ObjectIdentifier ExtendedKeyUsage_Id; + public static final ObjectIdentifier ExtendedKeyUsage_Id = + ObjectIdentifier.of(KnownOIDs.extendedKeyUsage); /** * Specifies whether any-policy policy OID is permitted */ - public static final ObjectIdentifier InhibitAnyPolicy_Id; + public static final ObjectIdentifier InhibitAnyPolicy_Id = + ObjectIdentifier.of(KnownOIDs.InhibitAnyPolicy); /** * Identifies the certificate issuer associated with an entry in an * indirect CRL. */ - public static final ObjectIdentifier CertificateIssuer_Id; + public static final ObjectIdentifier CertificateIssuer_Id = + ObjectIdentifier.of(KnownOIDs.CertificateIssuer); /** * This extension indicates how to access CA information and services for @@ -212,73 +199,33 @@ * This information may be used for on-line certification validation * services. */ - public static final ObjectIdentifier AuthInfoAccess_Id; + public static final ObjectIdentifier AuthInfoAccess_Id = + ObjectIdentifier.of(KnownOIDs.AuthInfoAccess); /** * This extension indicates how to access CA information and services for * the subject of the certificate in which the extension appears. */ - public static final ObjectIdentifier SubjectInfoAccess_Id; + public static final ObjectIdentifier SubjectInfoAccess_Id = + ObjectIdentifier.of(KnownOIDs.SubjectInfoAccess); /** * Identifies how delta CRL information is obtained. */ - public static final ObjectIdentifier FreshestCRL_Id; + public static final ObjectIdentifier FreshestCRL_Id = + ObjectIdentifier.of(KnownOIDs.FreshestCRL); /** * Identifies the OCSP client can trust the responder for the * lifetime of the responder's certificate. */ - public static final ObjectIdentifier OCSPNoCheck_Id; + public static final ObjectIdentifier OCSPNoCheck_Id = + ObjectIdentifier.of(KnownOIDs.OCSPNoCheck); /** * This extension is used to provide nonce data for OCSP requests * or responses. */ - public static final ObjectIdentifier OCSPNonce_Id; - - static { - AuthorityKey_Id = ObjectIdentifier.newInternal(AuthorityKey_data); - SubjectKey_Id = ObjectIdentifier.newInternal(SubjectKey_data); - KeyUsage_Id = ObjectIdentifier.newInternal(KeyUsage_data); - PrivateKeyUsage_Id = ObjectIdentifier.newInternal(PrivateKeyUsage_data); - CertificatePolicies_Id = - ObjectIdentifier.newInternal(CertificatePolicies_data); - PolicyMappings_Id = ObjectIdentifier.newInternal(PolicyMappings_data); - SubjectAlternativeName_Id = - ObjectIdentifier.newInternal(SubjectAlternativeName_data); - IssuerAlternativeName_Id = - ObjectIdentifier.newInternal(IssuerAlternativeName_data); - ExtendedKeyUsage_Id = ObjectIdentifier.newInternal(ExtendedKeyUsage_data); - InhibitAnyPolicy_Id = ObjectIdentifier.newInternal(InhibitAnyPolicy_data); - SubjectDirectoryAttributes_Id = - ObjectIdentifier.newInternal(SubjectDirectoryAttributes_data); - BasicConstraints_Id = - ObjectIdentifier.newInternal(BasicConstraints_data); - ReasonCode_Id = ObjectIdentifier.newInternal(ReasonCode_data); - HoldInstructionCode_Id = - ObjectIdentifier.newInternal(HoldInstructionCode_data); - InvalidityDate_Id = ObjectIdentifier.newInternal(InvalidityDate_data); - - NameConstraints_Id = ObjectIdentifier.newInternal(NameConstraints_data); - PolicyConstraints_Id = - ObjectIdentifier.newInternal(PolicyConstraints_data); - CRLDistributionPoints_Id = - ObjectIdentifier.newInternal(CRLDistributionPoints_data); - CRLNumber_Id = - ObjectIdentifier.newInternal(CRLNumber_data); - IssuingDistributionPoint_Id = - ObjectIdentifier.newInternal(IssuingDistributionPoint_data); - DeltaCRLIndicator_Id = - ObjectIdentifier.newInternal(DeltaCRLIndicator_data); - CertificateIssuer_Id = - ObjectIdentifier.newInternal(CertificateIssuer_data); - AuthInfoAccess_Id = - ObjectIdentifier.newInternal(AuthInfoAccess_data); - SubjectInfoAccess_Id = - ObjectIdentifier.newInternal(SubjectInfoAccess_data); - FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data); - OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data); - OCSPNonce_Id = ObjectIdentifier.newInternal(OCSPNonce_data); - } + public static final ObjectIdentifier OCSPNonce_Id = + ObjectIdentifier.of(KnownOIDs.OCSPNonceExt); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X500Name.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X500Name.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X500Name.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X500Name.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1102,104 +1102,83 @@ * Includes all those specified in RFC 5280 as MUST or SHOULD * be recognized */ - private static final int[] commonName_data = { 2, 5, 4, 3 }; - private static final int[] SURNAME_DATA = { 2, 5, 4, 4 }; - private static final int[] SERIALNUMBER_DATA = { 2, 5, 4, 5 }; - private static final int[] countryName_data = { 2, 5, 4, 6 }; - private static final int[] localityName_data = { 2, 5, 4, 7 }; - private static final int[] stateName_data = { 2, 5, 4, 8 }; - private static final int[] streetAddress_data = { 2, 5, 4, 9 }; - private static final int[] orgName_data = { 2, 5, 4, 10 }; - private static final int[] orgUnitName_data = { 2, 5, 4, 11 }; - private static final int[] title_data = { 2, 5, 4, 12 }; - private static final int[] GIVENNAME_DATA = { 2, 5, 4, 42 }; - private static final int[] INITIALS_DATA = { 2, 5, 4, 43 }; - private static final int[] GENERATIONQUALIFIER_DATA = { 2, 5, 4, 44 }; - private static final int[] DNQUALIFIER_DATA = { 2, 5, 4, 46 }; - - private static final int[] ipAddress_data = { 1, 3, 6, 1, 4, 1, 42, 2, 11, 2, 1 }; - private static final int[] DOMAIN_COMPONENT_DATA = - { 0, 9, 2342, 19200300, 100, 1, 25 }; - private static final int[] userid_data = - { 0, 9, 2342, 19200300, 100, 1, 1 }; - // OID for the "CN=" attribute, denoting a person's common name. public static final ObjectIdentifier commonName_oid = - ObjectIdentifier.newInternal(commonName_data); + ObjectIdentifier.of(KnownOIDs.CommonName); + + // OID for the "SURNAME=" attribute, denoting a person's surname. + public static final ObjectIdentifier SURNAME_OID = + ObjectIdentifier.of(KnownOIDs.Surname); // OID for the "SERIALNUMBER=" attribute, denoting a serial number for. // a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the // certificate serial number. public static final ObjectIdentifier SERIALNUMBER_OID = - ObjectIdentifier.newInternal(SERIALNUMBER_DATA); + ObjectIdentifier.of(KnownOIDs.SerialNumber); // OID for the "C=" attribute, denoting a country. public static final ObjectIdentifier countryName_oid = - ObjectIdentifier.newInternal(countryName_data); + ObjectIdentifier.of(KnownOIDs.CountryName); // OID for the "L=" attribute, denoting a locality (such as a city). public static final ObjectIdentifier localityName_oid = - ObjectIdentifier.newInternal(localityName_data); - - // OID for the "O=" attribute, denoting an organization name. - public static final ObjectIdentifier orgName_oid = - ObjectIdentifier.newInternal(orgName_data); - - // OID for the "OU=" attribute, denoting an organizational unit name. - public static final ObjectIdentifier orgUnitName_oid = - ObjectIdentifier.newInternal(orgUnitName_data); + ObjectIdentifier.of(KnownOIDs.LocalityName); // OID for the "S=" attribute, denoting a state (such as Delaware). public static final ObjectIdentifier stateName_oid = - ObjectIdentifier.newInternal(stateName_data); + ObjectIdentifier.of(KnownOIDs.StateName); // OID for the "STREET=" attribute, denoting a street address. public static final ObjectIdentifier streetAddress_oid = - ObjectIdentifier.newInternal(streetAddress_data); + ObjectIdentifier.of(KnownOIDs.StreetAddress); - // OID for the "T=" attribute, denoting a person's title. - public static final ObjectIdentifier title_oid = - ObjectIdentifier.newInternal(title_data); + // OID for the "O=" attribute, denoting an organization name. + public static final ObjectIdentifier orgName_oid = + ObjectIdentifier.of(KnownOIDs.OrgName); - // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN - // disambiguating information. - public static final ObjectIdentifier DNQUALIFIER_OID = - ObjectIdentifier.newInternal(DNQUALIFIER_DATA); + // OID for the "OU=" attribute, denoting an organizational unit name. + public static final ObjectIdentifier orgUnitName_oid = + ObjectIdentifier.of(KnownOIDs.OrgUnitName); - // OID for the "SURNAME=" attribute, denoting a person's surname. - public static final ObjectIdentifier SURNAME_OID = - ObjectIdentifier.newInternal(SURNAME_DATA); + // OID for the "T=" attribute, denoting a person's title. + public static final ObjectIdentifier title_oid = + ObjectIdentifier.of(KnownOIDs.Title); // OID for the "GIVENNAME=" attribute, denoting a person's given name. public static final ObjectIdentifier GIVENNAME_OID = - ObjectIdentifier.newInternal(GIVENNAME_DATA); + ObjectIdentifier.of(KnownOIDs.GivenName); // OID for the "INITIALS=" attribute, denoting a person's initials. public static final ObjectIdentifier INITIALS_OID = - ObjectIdentifier.newInternal(INITIALS_DATA); + ObjectIdentifier.of(KnownOIDs.Initials); // OID for the "GENERATION=" attribute, denoting Jr., II, etc. public static final ObjectIdentifier GENERATIONQUALIFIER_OID = - ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA); + ObjectIdentifier.of(KnownOIDs.GenerationQualifier); + + // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN + // disambiguating information. + public static final ObjectIdentifier DNQUALIFIER_OID = + ObjectIdentifier.of(KnownOIDs.DNQualifier); // OIDs from other sources which show up in X.500 names we // expect to deal with often. // // OID for "IP=" IP address attributes, used with SKIP. public static final ObjectIdentifier ipAddress_oid = - ObjectIdentifier.newInternal(ipAddress_data); + ObjectIdentifier.of(KnownOIDs.SkipIPAddress); // Domain component OID from RFC 1274, RFC 2247, RFC 5280. // - // OID for "DC=" domain component attributes, used with DNSNames in DN + // OID for "DC=" domain component attributes.used with DNSNames in DN // format. public static final ObjectIdentifier DOMAIN_COMPONENT_OID = - ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA); + ObjectIdentifier.of(KnownOIDs.UCL_DomainComponent); // OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. public static final ObjectIdentifier userid_oid = - ObjectIdentifier.newInternal(userid_data); + ObjectIdentifier.of(KnownOIDs.UCL_UserID); /** * Return constraint type:

    diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X509CertImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X509CertImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X509CertImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X509CertImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. * 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,13 +25,7 @@ package sun.security.x509; -import java.io.BufferedReader; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; +import java.io.*; import java.math.BigInteger; import java.security.*; import java.security.spec.AlgorithmParameterSpec; @@ -42,6 +36,7 @@ import javax.security.auth.x500.X500Principal; +import sun.security.jca.JCAUtil; import sun.security.util.*; import sun.security.provider.X509Factory; @@ -130,14 +125,6 @@ protected AlgorithmId algId = null; protected byte[] signature = null; - // recognized extension OIDS - private static final String KEY_USAGE_OID = "2.5.29.15"; - private static final String EXTENDED_KEY_USAGE_OID = "2.5.29.37"; - private static final String BASIC_CONSTRAINT_OID = "2.5.29.19"; - private static final String SUBJECT_ALT_NAME_OID = "2.5.29.17"; - private static final String ISSUER_ALT_NAME_OID = "2.5.29.18"; - private static final String AUTH_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.1"; - // number of standard key usage bits. private static final int NUM_STANDARD_KEY_USAGE = 9; @@ -312,6 +299,13 @@ } } + // helper method to record certificate, if necessary, after construction + public static X509CertImpl newX509CertImpl(byte[] certData) throws CertificateException { + var cert = new X509CertImpl(certData); + JCAUtil.tryCommitCertEvent(cert); + return cert; + } + /** * Appends the certificate to an output stream. * @@ -677,7 +671,7 @@ /** * Return the requested attribute from the certificate. - * + *

    * Note that the X509CertInfo is not cloned for performance reasons. * Callers must ensure that they do not modify it. All other * attributes are cloned. @@ -1425,7 +1419,7 @@ */ public byte[] getExtensionValue(String oid) { try { - ObjectIdentifier findOID = new ObjectIdentifier(oid); + ObjectIdentifier findOID = ObjectIdentifier.of(oid); String extAlias = OIDMap.getName(findOID); Extension certExt = null; CertificateExtensions exts = (CertificateExtensions)info.get( @@ -1528,7 +1522,8 @@ public static List getExtendedKeyUsage(X509Certificate cert) throws CertificateParsingException { try { - byte[] ext = cert.getExtensionValue(EXTENDED_KEY_USAGE_OID); + byte[] ext = cert.getExtensionValue + (KnownOIDs.extendedKeyUsage.value()); if (ext == null) return null; DerValue val = new DerValue(ext); @@ -1585,7 +1580,7 @@ for (GeneralName gname : names.names()) { GeneralNameInterface name = gname.getName(); List nameEntry = new ArrayList<>(2); - nameEntry.add(Integer.valueOf(name.getType())); + nameEntry.add(name.getType()); switch (name.getType()) { case GeneralNameInterface.NAME_RFC822: nameEntry.add(((RFC822Name) name).getName()); @@ -1698,7 +1693,8 @@ public static Collection> getSubjectAlternativeNames(X509Certificate cert) throws CertificateParsingException { try { - byte[] ext = cert.getExtensionValue(SUBJECT_ALT_NAME_OID); + byte[] ext = cert.getExtensionValue + (KnownOIDs.SubjectAlternativeName.value()); if (ext == null) { return null; } @@ -1761,7 +1757,8 @@ public static Collection> getIssuerAlternativeNames(X509Certificate cert) throws CertificateParsingException { try { - byte[] ext = cert.getExtensionValue(ISSUER_ALT_NAME_OID); + byte[] ext = cert.getExtensionValue + (KnownOIDs.IssuerAlternativeName.value()); if (ext == null) { return null; } @@ -2005,4 +2002,19 @@ buf.append(hexChars[high]) .append(hexChars[low]); } + + /** + * Restores the state of this object from the stream. + *

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "X509CertImpls are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X509CRLEntryImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -252,7 +252,8 @@ */ public static CRLReason getRevocationReason(X509CRLEntry crlEntry) { try { - byte[] ext = crlEntry.getExtensionValue("2.5.29.21"); + byte[] ext = crlEntry.getExtensionValue + (KnownOIDs.ReasonCode.value()); if (ext == null) { return null; } @@ -402,11 +403,11 @@ if (extensions == null) return null; try { - String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); + String extAlias = OIDMap.getName(ObjectIdentifier.of(oid)); Extension crlExt = null; if (extAlias == null) { // may be unknown - ObjectIdentifier findOID = new ObjectIdentifier(oid); + ObjectIdentifier findOID = ObjectIdentifier.of(oid); Extension ex = null; ObjectIdentifier inCertOID; for (Enumeration e = extensions.getElements(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1036,11 +1036,11 @@ if (extensions == null) return null; try { - String extAlias = OIDMap.getName(new ObjectIdentifier(oid)); + String extAlias = OIDMap.getName(ObjectIdentifier.of(oid)); Extension crlExt = null; if (extAlias == null) { // may be unknown - ObjectIdentifier findOID = new ObjectIdentifier(oid); + ObjectIdentifier findOID = ObjectIdentifier.of(oid); Extension ex = null; ObjectIdentifier inCertOID; for (Enumeration e = extensions.getElements(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/text/bidi/BidiBase.java openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/text/bidi/BidiBase.java --- openjdk-lts-11.0.20.1+1/src/java.base/share/classes/sun/text/bidi/BidiBase.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/classes/sun/text/bidi/BidiBase.java 2023-10-06 05:33:33.000000000 +0000 @@ -4592,7 +4592,7 @@ levelStart + " is out of range 0 to " + (objects.length-1)); } - if (0 > count || objects.length < (objectStart+count)) { + if (0 > count || objects.length - count < objectStart) { throw new IllegalArgumentException("Value count " + levelStart + " is out of range 0 to " + (objects.length - objectStart)); diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/conf/security/java.security openjdk-lts-11.0.21+9/src/java.base/share/conf/security/java.security --- openjdk-lts-11.0.20.1+1/src/java.base/share/conf/security/java.security 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/conf/security/java.security 2023-10-06 05:33:33.000000000 +0000 @@ -22,6 +22,9 @@ # the command line, set the key security.overridePropertiesFile # to false in the master security properties file. It is set to true # by default. +# +# If this properties file fails to load, the JDK implementation will throw +# an unspecified error when initializing the java.security.Security class. # In this file, various security properties are set for use by # java.security classes. This is where users can statically register diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/share/legal/public_suffix.md openjdk-lts-11.0.21+9/src/java.base/share/legal/public_suffix.md --- openjdk-lts-11.0.20.1+1/src/java.base/share/legal/public_suffix.md 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/share/legal/public_suffix.md 2023-10-06 05:33:33.000000000 +0000 @@ -11,7 +11,7 @@ The Source Code of this file is available under the Mozilla Public License, v. 2.0 and is located at -https://raw.githubusercontent.com/publicsuffix/list/3c213aab32b3c014f171b1673d4ce9b5cd72bf1c/public_suffix_list.dat. +https://raw.githubusercontent.com/publicsuffix/list/88467c960d6cdad2ca1623e892e5e17506bc269f/public_suffix_list.dat. If a copy of the MPL was not distributed with this file, you can obtain one at https://mozilla.org/MPL/2.0/. diff -Nru openjdk-lts-11.0.20.1+1/src/java.base/windows/native/libnet/DefaultProxySelector.c openjdk-lts-11.0.21+9/src/java.base/windows/native/libnet/DefaultProxySelector.c --- openjdk-lts-11.0.20.1+1/src/java.base/windows/native/libnet/DefaultProxySelector.c 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.base/windows/native/libnet/DefaultProxySelector.c 2023-10-06 05:33:33.000000000 +0000 @@ -243,7 +243,7 @@ if (use_auto_proxy) { WCHAR url[MAX_STR_LEN]; /* Create url for WinHttpGetProxyForUrl */ - _snwprintf(url, sizeof(url) - 1, L"%s://%s", lpProto, lpHost); + swprintf(url, MAX_STR_LEN, L"%s://%s", lpProto, lpHost); /* Get proxy for URL from Windows */ use_auto_proxy = WinHttpGetProxyForUrl(session, &url[0], &auto_proxy_options, &proxy_info); if (use_auto_proxy) { diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java openjdk-lts-11.0.21+9/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java --- openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java 2023-10-06 05:33:33.000000000 +0000 @@ -45,6 +45,7 @@ import javax.print.attribute.standard.MediaSize; import javax.print.attribute.standard.MediaSizeName; import javax.print.attribute.standard.PageRanges; +import javax.print.attribute.standard.Sides; import javax.print.attribute.Attribute; import sun.java2d.*; @@ -630,7 +631,8 @@ } catch (Exception e) { return null; } - return page; + + return FlipPageFormat.flipPage(page); } private Printable getPrintable(int pageIndex) { @@ -682,6 +684,24 @@ return pageFormatArea; } + private int getSides() { + return (this.sidesAttr == null) ? -1 : this.sidesAttr.getValue(); + } + + private void setSides(int sides) { + if (attributes == null) { + return; + } + + final Sides[] sidesTable = new Sides[] {Sides.ONE_SIDED, Sides.TWO_SIDED_LONG_EDGE, Sides.TWO_SIDED_SHORT_EDGE}; + + if (sides >= 0 && sides < sidesTable.length) { + Sides s = sidesTable[sides]; + attributes.add(s); + this.sidesAttr = s; + } + } + private boolean cancelCheck() { // This is called from the native side. @@ -730,7 +750,7 @@ Graphics2D pathGraphics = new CPrinterGraphics(delegate, printerJob); // Just stores delegate into an ivar Rectangle2D pageFormatArea = getPageFormatArea(page); initPrinterGraphics(pathGraphics, pageFormatArea); - painter.print(pathGraphics, page, pageIndex); + painter.print(pathGraphics, FlipPageFormat.getOriginal(page), pageIndex); delegate.dispose(); delegate = null; } catch (PrinterException pe) { throw new java.lang.reflect.UndeclaredThrowableException(pe); } @@ -757,7 +777,7 @@ Runnable r = new Runnable() { public void run() { synchronized(ret) { try { Pageable pageable = getPageable(); - PageFormat pageFormat = pageable.getPageFormat(pageIndex); + PageFormat pageFormat = getPageFormat(pageIndex); if (pageFormat != null) { Printable printable = pageable.getPrintable(pageIndex); if (printable != null) { @@ -870,4 +890,75 @@ (float) (paper.getImageableHeight() / dpi), MediaPrintableArea.INCH); } + + // MacOS NSPrintInfo class has one to one correspondence + // between a paper size and its orientation. + // NSPrintInfo with paper width less than height + // has portrait orientation. + // NSPrintInfo with paper width greater than height + // has landscape orientation. + // (w < h) <-> portrait + // (w > h) <-> landscape + // + // Java PageFormat class has the following relation with NSPrintInfo: + // 1. PageFormat: + // page size: width < height + // orientation: portrait + // NSPrintInfo: width < height (portrait orientation) + // 2. PageFormat: + // page size: width < height + // orientation: landscape + // NSPrintInfo: width > height (landscape orientation) + // + // FlipPageFormat class establishes correspondence between + // Java PageFormat class which page width is greater than height + // with NSPrintInfo in the following way: + // 3. PageFormat: + // page size: width > height + // orientation: portrait + // FlipPageFormat + // page size: width < height + // orientation: landscape + // NSPrintInfo: width > height (landscape orientation) + // 4. PageFormat: + // page size: width > height + // orientation: landscape + // FlipPageFormat + // page size: width < height + // orientation: portrait + // NSPrintInfo: width < height (portrait orientation) + // + // FlipPageFormat preserves the original PageFormat class + // to pass it to Printable.print(Graphics, PageFormat, int) + // method overridden by a user. + private static class FlipPageFormat extends PageFormat { + + private final PageFormat original; + + private FlipPageFormat(PageFormat original) { + this.original = original; + Paper paper = original.getPaper(); + Paper copyPaper = this.getPaper(); + copyPaper.setSize(paper.getHeight(), paper.getWidth()); + copyPaper.setImageableArea( + paper.getImageableY(), paper.getImageableX(), + paper.getImageableHeight(), paper.getImageableWidth()); + this.setPaper(copyPaper); + this.setOrientation((original.getOrientation() == PageFormat.PORTRAIT) + ? PageFormat.LANDSCAPE + : PageFormat.PORTRAIT); + } + + private static PageFormat getOriginal(PageFormat page) { + return (page instanceof FlipPageFormat) ? ((FlipPageFormat) page).original : page; + } + + private static PageFormat flipPage(PageFormat page) { + if (page == null) { + return null; + } + Paper paper = page.getPaper(); + return (paper.getWidth() > paper.getHeight()) ? new FlipPageFormat(page) : page; + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m --- openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libawt_lwawt/awt/CClipboard.m 2023-10-06 05:33:33.000000000 +0000 @@ -136,15 +136,16 @@ jint nElements = (*env)->GetArrayLength(env, inTypes); NSMutableArray *formatArray = [NSMutableArray arrayWithCapacity:nElements]; jlong *elements = (*env)->GetPrimitiveArrayCritical(env, inTypes, NULL); + if (elements != NULL) { + for (i = 0; i < nElements; i++) { + NSString *pbFormat = formatForIndex(elements[i]); + if (pbFormat) + [formatArray addObject:pbFormat]; + } - for (i = 0; i < nElements; i++) { - NSString *pbFormat = formatForIndex(elements[i]); - if (pbFormat) - [formatArray addObject:pbFormat]; + (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT); + [[CClipboard sharedClipboard] declareTypes:formatArray withOwner:inJavaClip jniEnv:env]; } - - (*env)->ReleasePrimitiveArrayCritical(env, inTypes, elements, JNI_ABORT); - [[CClipboard sharedClipboard] declareTypes:formatArray withOwner:inJavaClip jniEnv:env]; JNI_COCOA_EXIT(env); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m --- openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libawt_lwawt/awt/CPrinterJob.m 2023-10-06 05:33:33.000000000 +0000 @@ -37,6 +37,10 @@ #import "GeomUtilities.h" #import "JNIUtilities.h" +#define ONE_SIDED 0 +#define TWO_SIDED_LONG_EDGE 1 +#define TWO_SIDED_SHORT_EDGE 2 + static jclass sjc_Paper = NULL; static jclass sjc_PageFormat = NULL; static jclass sjc_CPrinterJob = NULL; @@ -351,6 +355,24 @@ [dstPrintInfo setPrinter:printer]; } +static jint duplexModeToSides(PMDuplexMode duplexMode) { + switch(duplexMode) { + case kPMDuplexNone: return ONE_SIDED; + case kPMDuplexTumble: return TWO_SIDED_SHORT_EDGE; + case kPMDuplexNoTumble: return TWO_SIDED_LONG_EDGE; + default: return -1; + } +} + +static PMDuplexMode sidesToDuplexMode(jint sides) { + switch(sides) { + case ONE_SIDED: return kPMDuplexNone; + case TWO_SIDED_SHORT_EDGE: return kPMDuplexTumble; + case TWO_SIDED_LONG_EDGE: return kPMDuplexNoTumble; + default: return kPMDuplexNone; + } +} + static void nsPrintInfoToJavaPrinterJob(JNIEnv* env, NSPrintInfo* src, jobject dstPrinterJob, jobject dstPageable) { GET_CPRINTERJOB_CLASS(); @@ -360,6 +382,7 @@ DECLARE_METHOD(jm_setPageRangeAttribute, sjc_CPrinterJob, "setPageRangeAttribute", "(IIZ)V"); DECLARE_METHOD(jm_setPrintToFile, sjc_CPrinterJob, "setPrintToFile", "(Z)V"); DECLARE_METHOD(jm_setDestinationFile, sjc_CPrinterJob, "setDestinationFile", "(Ljava/lang/String;)V"); + DECLARE_METHOD(jm_setSides, sjc_CPrinterJob, "setSides", "(I)V"); // get the selected printer's name, and set the appropriate PrintService on the Java side NSString *name = [[src printer] name]; @@ -420,6 +443,12 @@ jFirstPage, jLastPage, isRangeSet); // AWT_THREADING Safe (known object) CHECK_EXCEPTION(); + PMDuplexMode duplexSetting; + if (PMGetDuplex(src.PMPrintSettings, &duplexSetting) == noErr) { + jint sides = duplexModeToSides(duplexSetting); + (*env)->CallVoidMethod(env, dstPrinterJob, jm_setSides, sides); // AWT_THREADING Safe (known object) + CHECK_EXCEPTION(); + } } } @@ -438,6 +467,8 @@ DECLARE_METHOD(jm_getNumberOfPages, jc_Pageable, "getNumberOfPages", "()I"); DECLARE_METHOD(jm_getPageFormat, sjc_CPrinterJob, "getPageFormatFromAttributes", "()Ljava/awt/print/PageFormat;"); DECLARE_METHOD(jm_getDestinationFile, sjc_CPrinterJob, "getDestinationFile", "()Ljava/lang/String;"); + DECLARE_METHOD(jm_getSides, sjc_CPrinterJob, "getSides", "()I"); + NSMutableDictionary* printingDictionary = [dst dictionary]; @@ -496,6 +527,17 @@ } else { [dst setJobDisposition:NSPrintSpoolJob]; } + + jint sides = (*env)->CallIntMethod(env, srcPrinterJob, jm_getSides); + CHECK_EXCEPTION(); + + if (sides >= 0) { + PMDuplexMode duplexMode = sidesToDuplexMode(sides); + PMPrintSettings printSettings = dst.PMPrintSettings; + if (PMSetDuplex(printSettings, duplexMode) == noErr) { + [dst updateFromPMPrintSettings]; + } + } } /* diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m --- openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libawt_lwawt/font/CCharToGlyphMapper.m 2023-10-06 05:33:33.000000000 +0000 @@ -58,12 +58,14 @@ { jint *glyphCodeInts = (*env)->GetPrimitiveArrayCritical(env, glyphs, 0); - CTS_GetGlyphsAsIntsForCharacters(awtFont, unicodes, - cgGlyphs, glyphCodeInts, count); + if (glyphCodeInts != NULL) { + CTS_GetGlyphsAsIntsForCharacters(awtFont, unicodes, + cgGlyphs, glyphCodeInts, count); - // Do not use JNI_COMMIT, as that will not free the buffer copy - // when +ProtectJavaHeap is on. - (*env)->ReleasePrimitiveArrayCritical(env, glyphs, glyphCodeInts, 0); + // Do not use JNI_COMMIT, as that will not free the buffer copy + // when +ProtectJavaHeap is on. + (*env)->ReleasePrimitiveArrayCritical(env, glyphs, glyphCodeInts, 0); + } } static inline void diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libosxui/JRSUIController.m openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libosxui/JRSUIController.m --- openjdk-lts-11.0.20.1+1/src/java.desktop/macosx/native/libosxui/JRSUIController.m 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/macosx/native/libosxui/JRSUIController.m 2023-10-06 05:33:33.000000000 +0000 @@ -277,11 +277,13 @@ CGRect partBounds = JRSUIControlGetScrollBarPartBounds(control, frame, part); jdouble *rect = (*env)->GetPrimitiveArrayCritical(env, rectArray, NULL); - rect[0] = partBounds.origin.x; - rect[1] = partBounds.origin.y; - rect[2] = partBounds.size.width; - rect[3] = partBounds.size.height; - (*env)->ReleasePrimitiveArrayCritical(env, rectArray, rect, 0); + if (rect != NULL) { + rect[0] = partBounds.origin.x; + rect[1] = partBounds.origin.y; + rect[2] = partBounds.size.width; + rect[3] = partBounds.size.height; + (*env)->ReleasePrimitiveArrayCritical(env, rectArray, rect, 0); + } } /* diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java openjdk-lts-11.0.21+9/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java 2023-10-06 05:33:33.000000000 +0000 @@ -1377,8 +1377,9 @@ } } while (doIO && thread == curThread) { - if (newFramePosition >= 0) { - clipBytePosition = newFramePosition * frameSize; + int npf = newFramePosition; // copy into local variable + if (npf >= 0) { + clipBytePosition = npf * frameSize; newFramePosition = -1; } int endFrame = getFrameLength() - 1; diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/sun/awt/FontConfiguration.java openjdk-lts-11.0.21+9/src/java.desktop/share/classes/sun/awt/FontConfiguration.java --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/sun/awt/FontConfiguration.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/share/classes/sun/awt/FontConfiguration.java 2023-10-06 05:33:33.000000000 +0000 @@ -1252,15 +1252,24 @@ return filenamesMap.get(platformName); } + private static final String fontconfigErrorMessage = + "Fontconfig head is null, check your fonts or fonts configuration"; + /** * Returns a configuration specific path to be appended to the font * search path. */ public String getExtraFontPath() { + if (head == null) { + throw new RuntimeException(fontconfigErrorMessage); + } return getString(head[INDEX_appendedfontpath]); } public String getVersion() { + if (head == null) { + throw new RuntimeException(fontconfigErrorMessage); + } return getString(head[INDEX_version]); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java openjdk-lts-11.0.21+9/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. * 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,24 +27,20 @@ import java.awt.Color; import java.awt.Graphics; -import java.awt.Transparency; -import java.awt.AWTException; +import java.awt.Graphics2D; import java.awt.Rectangle; +import java.awt.Transparency; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; import java.awt.image.DirectColorModel; -import java.awt.image.IndexColorModel; import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; -import sun.awt.image.ByteComponentRaster; -import sun.awt.image.IntegerComponentRaster; +import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; -import java.awt.image.DataBuffer; -import java.awt.image.DataBufferInt; -import java.awt.Graphics2D; -import java.awt.geom.AffineTransform; -import sun.awt.image.ImageWatched; import java.util.Hashtable; public class ImageRepresentation extends ImageWatched implements ImageConsumer @@ -114,8 +110,8 @@ try { startProduction(); missinginfo = flags & ~availinfo; - while ((availinfo & ImageObserver.ERROR) == 0 && - missinginfo != 0) + while ((availinfo & (ImageObserver.ERROR | ImageObserver.FRAMEBITS)) == 0 + && missinginfo != 0) { try { wait(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java openjdk-lts-11.0.21+9/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java 2023-10-06 05:33:33.000000000 +0000 @@ -1077,6 +1077,8 @@ return false; } + this.attributes = attributes; + if (!service.equals(newService)) { try { setPrintService(newService); diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/legal/freetype.md openjdk-lts-11.0.21+9/src/java.desktop/share/legal/freetype.md --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/legal/freetype.md 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/share/legal/freetype.md 2023-10-06 05:33:33.000000000 +0000 @@ -1,4 +1,4 @@ -## The FreeType Project: Freetype v2.12.1 +## The FreeType Project: Freetype v2.13.0 ### FreeType Notice @@ -21,27 +21,26 @@ ### FreeType License ``` -Copyright (C) 1996-2022 by David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright (C) 2007-2022 by Dereg Clegg and Michael Toftdal. -Copyright (C) 1996-2022 by Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright (C) 2004-2022 by Masatake YAMATO and Redhat K.K. -Copyright (C) 2007-2022 by Derek Clegg and Michael Toftdal. -Copyright (C) 2007-2022 by David Turner. -Copyright (C) 2022 by David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti. -Copyright (C) 2007-2022 by Rahul Bhalerao , . -Copyright (C) 2008-2022 by David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. -Copyright (C) 2019-2022 by Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright (C) 2009-2022 by Oran Agra and Mickey Gabel. -Copyright (C) 2004-2022 by David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. -Copyright (C) 2004-2022 by Masatake YAMATO, Red Hat K.K., -Copyright (C) 2003-2022 by Masatake YAMATO, Redhat K.K., -Copyright (C) 2013-2022 by Google, Inc. -Copyright (C) 2018-2022 by David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg. -Copyright (C) 2005-2022 by David Turner, Robert Wilhelm, and Werner Lemberg. -Copyright 2013 by Google, Inc. +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. - The FreeType Project LICENSE + The FreeType Project LICENSE ---------------------------- 2006-Jan-27 @@ -206,7 +205,7 @@ Our home page can be found at - http://www.freetype.org + https://www.freetype.org ``` diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/legal/harfbuzz.md openjdk-lts-11.0.21+9/src/java.desktop/share/legal/harfbuzz.md --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/legal/harfbuzz.md 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.desktop/share/legal/harfbuzz.md 2023-10-06 05:33:33.000000000 +0000 @@ -1,8 +1,8 @@ -## Harfbuzz v7.0.1 +## Harfbuzz v7.2.0 ### Harfbuzz License -https://github.com/harfbuzz/harfbuzz/blob/7.0.1/COPYING +https://github.com/harfbuzz/harfbuzz/blob/7.2.0/COPYING

     
    @@ -10,7 +10,7 @@
     For parts of HarfBuzz that are licensed under different licenses see individual
     files names COPYING in subdirectories where applicable.
     
    -Copyright © 2010-2022  Google, Inc.
    +Copyright © 2010-2023  Google, Inc.
     Copyright © 2018-2020  Ebrahim Byagowi
     Copyright © 2004-2013  Red Hat, Inc.
     Copyright © 2019  Facebook, Inc.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/legal/libpng.md openjdk-lts-11.0.21+9/src/java.desktop/share/legal/libpng.md
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/legal/libpng.md	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/legal/libpng.md	2023-10-06 05:33:33.000000000 +0000
    @@ -1,4 +1,4 @@
    -## libpng v1.6.38
    +## libpng v1.6.39
     
     ### libpng License
     
    @@ -188,9 +188,10 @@
      * Arm Holdings
        - Richard Townsend
      * Google Inc.
    +   - Dan Field
    +   - Leon Scroggins III
        - Matt Sarett
        - Mike Klein
    -   - Dan Field
        - Sami Boukortt
     
     The build projects, the build scripts, the test scripts, and other
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libawt/java2d/loops/FourByteAbgrPre.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libawt/java2d/loops/FourByteAbgrPre.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libawt/java2d/loops/FourByteAbgrPre.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libawt/java2d/loops/FourByteAbgrPre.c	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 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
    @@ -69,6 +69,8 @@
     DECLARE_ALPHA_MASKBLIT(IntArgb, FourByteAbgrPre);
     DECLARE_SRCOVER_MASKBLIT(IntArgbPre, FourByteAbgrPre);
     DECLARE_ALPHA_MASKBLIT(IntArgbPre, FourByteAbgrPre);
    +DECLARE_SRCOVER_MASKBLIT(FourByteAbgrPre, IntArgbPre);
    +DECLARE_ALPHA_MASKBLIT(FourByteAbgrPre, IntArgbPre);
     DECLARE_ALPHA_MASKBLIT(IntRgb, FourByteAbgrPre);
     DECLARE_SOLID_DRAWGLYPHLISTAA(FourByteAbgrPre);
     DECLARE_SOLID_DRAWGLYPHLISTLCD(FourByteAbgrPre);
    @@ -103,6 +105,8 @@
         REGISTER_ALPHA_MASKBLIT(IntArgb, FourByteAbgrPre),
         REGISTER_SRCOVER_MASKBLIT(IntArgbPre, FourByteAbgrPre),
         REGISTER_ALPHA_MASKBLIT(IntArgbPre, FourByteAbgrPre),
    +    REGISTER_SRCOVER_MASKBLIT(FourByteAbgrPre, IntArgbPre),
    +    REGISTER_ALPHA_MASKBLIT(FourByteAbgrPre, IntArgbPre),
         REGISTER_ALPHA_MASKBLIT(IntRgb, FourByteAbgrPre),
         REGISTER_SOLID_DRAWGLYPHLISTAA(FourByteAbgrPre),
         REGISTER_SOLID_DRAWGLYPHLISTLCD(FourByteAbgrPre),
    @@ -177,6 +181,10 @@
     
     DEFINE_ALPHA_MASKBLIT(IntArgbPre, FourByteAbgrPre, 4ByteArgb)
     
    +DEFINE_SRCOVER_MASKBLIT(FourByteAbgrPre, IntArgbPre, 4ByteArgb)
    +
    +DEFINE_ALPHA_MASKBLIT(FourByteAbgrPre, IntArgbPre, 4ByteArgb)
    +
     DEFINE_ALPHA_MASKBLIT(IntRgb, FourByteAbgrPre, 4ByteArgb)
     
     DEFINE_SOLID_DRAWGLYPHLISTAA(FourByteAbgrPre, 4ByteArgb)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfontmanager/freetypeScaler.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfontmanager/freetypeScaler.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2007, 2021, 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
    @@ -466,7 +466,8 @@
         if ((aa != TEXT_AA_ON) && (fm != TEXT_FM_ON) &&
             !context->doBold && !context->doItalize &&
             (context->transform.yx == 0) && (context->transform.xy == 0) &&
    -        (context->transform.xx > 0) && (context->transform.yy > 0))
    +        (context->transform.xx > 0) && (context->transform.yy > 0) &&
    +        (context->transform.xx == context->transform.yy))
         {
             context->useSbits = 1;
         }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftconfig.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   ANSI-specific configuration file (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftheader.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Build macros of the FreeType 2 library.
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   User-selectable configuration macros (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -461,9 +461,9 @@
        *   while compiling in 'release' mode):
        *
        *   ```
    -   *     _af_debug_disable_horz_hints
    -   *     _af_debug_disable_vert_hints
    -   *     _af_debug_disable_blue_hints
    +   *     af_debug_disable_horz_hints_
    +   *     af_debug_disable_vert_hints_
    +   *     af_debug_disable_blue_hints_
        *   ```
        *
        *   Additionally, the following functions provide dumps of various
    @@ -480,7 +480,7 @@
        *   As an argument, they use another global variable:
        *
        *   ```
    -   *     _af_debug_hints
    +   *     af_debug_hints_
        *   ```
        *
        *   Please have a look at the `ftgrid` demo program to see how those
    @@ -584,12 +584,12 @@
       /**************************************************************************
        *
        * Define `TT_CONFIG_OPTION_POSTSCRIPT_NAMES` if you want to be able to
    -   * load and enumerate the glyph Postscript names in a TrueType or OpenType
    +   * load and enumerate Postscript names of glyphs in a TrueType or OpenType
        * file.
        *
    -   * Note that when you do not compile the 'psnames' module by undefining the
    -   * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES`, the 'sfnt' module will
    -   * contain additional code used to read the PS Names table from a font.
    +   * Note that if you do not compile the 'psnames' module by undefining the
    +   * above `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` macro, the 'sfnt' module will
    +   * contain additional code to read the PostScript name table from a font.
        *
        * (By default, the module uses 'psnames' to extract glyph names.)
        */
    @@ -740,6 +740,24 @@
     
     
       /**************************************************************************
    +   *
    +   * Define `TT_CONFIG_OPTION_NO_BORING_EXPANSION` if you want to exclude
    +   * support for 'boring' OpenType specification expansions.
    +   *
    +   *   https://github.com/harfbuzz/boring-expansion-spec
    +   *
    +   * Right now, the following features are covered:
    +   *
    +   *   - 'avar' version 2.0
    +   *
    +   * Most likely, this is a temporary configuration option to be removed in
    +   * the near future, since it is assumed that eventually those features are
    +   * added to the OpenType standard.
    +   */
    +/* #define TT_CONFIG_OPTION_NO_BORING_EXPANSION */
    +
    +
    +  /**************************************************************************
        *
        * Define `TT_CONFIG_OPTION_BDF` if you want to include support for an
        * embedded 'BDF~' table within SFNT-based bitmap formats.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   ANSI-specific library and header configuration file (specification
      *   only).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/integer-types.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType integer types definitions.
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/mac-support.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Mac/OS X support configuration header.
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/config/public-macros.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Define a set of compiler macros used in public FreeType headers.
      *
    - * Copyright (C) 2020-2022 by
    + * Copyright (C) 2020-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType high-level API and common types (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -215,7 +215,6 @@
        *   FT_Get_Char_Index
        *   FT_Get_First_Char
        *   FT_Get_Next_Char
    -   *   FT_Get_Name_Index
        *   FT_Load_Char
        *
        *   FT_OPEN_MEMORY
    @@ -254,14 +253,15 @@
        *   FT_Get_Kerning
        *   FT_Kerning_Mode
        *   FT_Get_Track_Kerning
    -   *   FT_Get_Glyph_Name
    -   *   FT_Get_Postscript_Name
        *
        *   FT_CharMapRec
        *   FT_Select_Charmap
        *   FT_Set_Charmap
        *   FT_Get_Charmap_Index
        *
    +   *   FT_Get_Name_Index
    +   *   FT_Get_Glyph_Name
    +   *   FT_Get_Postscript_Name
        *   FT_Get_FSType_Flags
        *   FT_Get_SubGlyph_Info
        *
    @@ -646,7 +646,7 @@
        *
        * @note:
        *   Despite the name, this enumeration lists specific character
    -   *   repertories (i.e., charsets), and not text encoding methods (e.g.,
    +   *   repertoires (i.e., charsets), and not text encoding methods (e.g.,
        *   UTF-8, UTF-16, etc.).
        *
        *   Other encodings might be defined in the future.
    @@ -779,7 +779,7 @@
        *   `encoding_id`.  If, for example, `encoding_id` is `TT_MAC_ID_ROMAN`
        *   and the language ID (minus~1) is `TT_MAC_LANGID_GREEK`, it is the
        *   Greek encoding, not Roman.  `TT_MAC_ID_ARABIC` with
    -   *   `TT_MAC_LANGID_FARSI` means the Farsi variant the Arabic encoding.
    +   *   `TT_MAC_LANGID_FARSI` means the Farsi variant of the Arabic encoding.
        */
       typedef enum  FT_Encoding_
       {
    @@ -1167,9 +1167,9 @@
        *   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 return 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 FreeType
    +   *     doesn't handle kerning data from the SFNT 'GPOS' table (as present
    +   *     in many OpenType fonts).
        *
        *   FT_FACE_FLAG_FAST_GLYPHS ::
        *     THIS FLAG IS DEPRECATED.  DO NOT USE OR TEST IT.
    @@ -1892,13 +1892,13 @@
        *     The advance width of the unhinted glyph.  Its value is expressed in
        *     16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when
        *     loading the glyph.  This field can be important to perform correct
    -   *     WYSIWYG layout.  Only relevant for outline glyphs.
    +   *     WYSIWYG layout.  Only relevant for scalable glyphs.
        *
        *   linearVertAdvance ::
        *     The advance height of the unhinted glyph.  Its value is expressed in
        *     16.16 fractional pixels, unless @FT_LOAD_LINEAR_DESIGN is set when
        *     loading the glyph.  This field can be important to perform correct
    -   *     WYSIWYG layout.  Only relevant for outline glyphs.
    +   *     WYSIWYG layout.  Only relevant for scalable glyphs.
        *
        *   advance ::
        *     This shorthand is, depending on @FT_LOAD_IGNORE_TRANSFORM, the
    @@ -2593,8 +2593,8 @@
        *   stream attachments.
        */
       FT_EXPORT( FT_Error )
    -  FT_Attach_Stream( FT_Face        face,
    -                    FT_Open_Args*  parameters );
    +  FT_Attach_Stream( FT_Face              face,
    +                    const FT_Open_Args*  parameters );
     
     
       /**************************************************************************
    @@ -3077,7 +3077,7 @@
        *
        *   FT_LOAD_NO_HINTING ::
        *     Disable hinting.  This generally generates 'blurrier' bitmap glyphs
    -   *     when the glyph are rendered in any of the anti-aliased modes.  See
    +   *     when the glyphs are rendered in any of the anti-aliased modes.  See
        *     also the note below.
        *
        *     This flag is implied by @FT_LOAD_NO_SCALE.
    @@ -3434,7 +3434,7 @@
        *     are not interested in the value.
        *
        *   delta ::
    -   *     A pointer a translation vector.  Set this to NULL if you are not
    +   *     A pointer to a translation vector.  Set this to NULL if you are not
        *     interested in the value.
        *
        * @since:
    @@ -3559,9 +3559,10 @@
        *
        *   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 intersect
    -   *      itself at some point; having these in your font definitely pose a
    -   *      problem to the rasterizer and cause artifacts, too.
    +   *      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
    @@ -3843,89 +3844,6 @@
       /**************************************************************************
        *
        * @function:
    -   *   FT_Get_Glyph_Name
    -   *
    -   * @description:
    -   *   Retrieve the ASCII name of a given glyph in a face.  This only works
    -   *   for those faces where @FT_HAS_GLYPH_NAMES(face) returns~1.
    -   *
    -   * @input:
    -   *   face ::
    -   *     A handle to a source face object.
    -   *
    -   *   glyph_index ::
    -   *     The glyph index.
    -   *
    -   *   buffer_max ::
    -   *     The maximum number of bytes available in the buffer.
    -   *
    -   * @output:
    -   *   buffer ::
    -   *     A pointer to a target buffer where the name is copied to.
    -   *
    -   * @return:
    -   *   FreeType error code.  0~means success.
    -   *
    -   * @note:
    -   *   An error is returned if the face doesn't provide glyph names or if the
    -   *   glyph index is invalid.  In all cases of failure, the first byte of
    -   *   `buffer` is set to~0 to indicate an empty name.
    -   *
    -   *   The glyph name is truncated to fit within the buffer if it is too
    -   *   long.  The returned string is always zero-terminated.
    -   *
    -   *   Be aware that FreeType reorders glyph indices internally so that glyph
    -   *   index~0 always corresponds to the 'missing glyph' (called '.notdef').
    -   *
    -   *   This function always returns an error if the config macro
    -   *   `FT_CONFIG_OPTION_NO_GLYPH_NAMES` is not defined in `ftoption.h`.
    -   */
    -  FT_EXPORT( FT_Error )
    -  FT_Get_Glyph_Name( FT_Face     face,
    -                     FT_UInt     glyph_index,
    -                     FT_Pointer  buffer,
    -                     FT_UInt     buffer_max );
    -
    -
    -  /**************************************************************************
    -   *
    -   * @function:
    -   *   FT_Get_Postscript_Name
    -   *
    -   * @description:
    -   *   Retrieve the ASCII PostScript name of a given face, if available.
    -   *   This only works with PostScript, TrueType, and OpenType fonts.
    -   *
    -   * @input:
    -   *   face ::
    -   *     A handle to the source face object.
    -   *
    -   * @return:
    -   *   A pointer to the face's PostScript name.  `NULL` if unavailable.
    -   *
    -   * @note:
    -   *   The returned pointer is owned by the face and is destroyed with it.
    -   *
    -   *   For variation fonts, this string changes if you select a different
    -   *   instance, and you have to call `FT_Get_PostScript_Name` again to
    -   *   retrieve it.  FreeType follows Adobe TechNote #5902, 'Generating
    -   *   PostScript Names for Fonts Using OpenType Font Variations'.
    -   *
    -   *     https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html
    -   *
    -   *   [Since 2.9] Special PostScript names for named instances are only
    -   *   returned if the named instance is set with @FT_Set_Named_Instance (and
    -   *   the font has corresponding entries in its 'fvar' table).  If
    -   *   @FT_IS_VARIATION returns true, the algorithmically derived PostScript
    -   *   name is provided, not looking up special entries for named instances.
    -   */
    -  FT_EXPORT( const char* )
    -  FT_Get_Postscript_Name( FT_Face  face );
    -
    -
    -  /**************************************************************************
    -   *
    -   * @function:
        *   FT_Select_Charmap
        *
        * @description:
    @@ -4243,7 +4161,8 @@
        *   FT_Get_Name_Index
        *
        * @description:
    -   *   Return the glyph index of a given glyph name.
    +   *   Return the glyph index of a given glyph name.  This only works
    +   *   for those faces where @FT_HAS_GLYPH_NAMES returns true.
        *
        * @input:
        *   face ::
    @@ -4254,6 +4173,16 @@
        *
        * @return:
        *   The glyph index.  0~means 'undefined character code'.
    +   *
    +   * @note:
    +   *   Acceptable glyph names might come from the [Adobe Glyph
    +   *   List](https://github.com/adobe-type-tools/agl-aglfn).  See
    +   *   @FT_Get_Glyph_Name for the inverse functionality.
    +   *
    +   *   This function has limited capabilities if the config macro
    +   *   `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` is not defined in `ftoption.h`:
    +   *   It then works only for fonts that actually embed glyph names (which
    +   *   many recent OpenType fonts do not).
        */
       FT_EXPORT( FT_UInt )
       FT_Get_Name_Index( FT_Face           face,
    @@ -4262,6 +4191,91 @@
     
       /**************************************************************************
        *
    +   * @function:
    +   *   FT_Get_Glyph_Name
    +   *
    +   * @description:
    +   *   Retrieve the ASCII name of a given glyph in a face.  This only works
    +   *   for those faces where @FT_HAS_GLYPH_NAMES returns true.
    +   *
    +   * @input:
    +   *   face ::
    +   *     A handle to a source face object.
    +   *
    +   *   glyph_index ::
    +   *     The glyph index.
    +   *
    +   *   buffer_max ::
    +   *     The maximum number of bytes available in the buffer.
    +   *
    +   * @output:
    +   *   buffer ::
    +   *     A pointer to a target buffer where the name is copied to.
    +   *
    +   * @return:
    +   *   FreeType error code.  0~means success.
    +   *
    +   * @note:
    +   *   An error is returned if the face doesn't provide glyph names or if the
    +   *   glyph index is invalid.  In all cases of failure, the first byte of
    +   *   `buffer` is set to~0 to indicate an empty name.
    +   *
    +   *   The glyph name is truncated to fit within the buffer if it is too
    +   *   long.  The returned string is always zero-terminated.
    +   *
    +   *   Be aware that FreeType reorders glyph indices internally so that glyph
    +   *   index~0 always corresponds to the 'missing glyph' (called '.notdef').
    +   *
    +   *   This function has limited capabilities if the config macro
    +   *   `FT_CONFIG_OPTION_POSTSCRIPT_NAMES` is not defined in `ftoption.h`:
    +   *   It then works only for fonts that actually embed glyph names (which
    +   *   many recent OpenType fonts do not).
    +   */
    +  FT_EXPORT( FT_Error )
    +  FT_Get_Glyph_Name( FT_Face     face,
    +                     FT_UInt     glyph_index,
    +                     FT_Pointer  buffer,
    +                     FT_UInt     buffer_max );
    +
    +
    +  /**************************************************************************
    +   *
    +   * @function:
    +   *   FT_Get_Postscript_Name
    +   *
    +   * @description:
    +   *   Retrieve the ASCII PostScript name of a given face, if available.
    +   *   This only works with PostScript, TrueType, and OpenType fonts.
    +   *
    +   * @input:
    +   *   face ::
    +   *     A handle to the source face object.
    +   *
    +   * @return:
    +   *   A pointer to the face's PostScript name.  `NULL` if unavailable.
    +   *
    +   * @note:
    +   *   The returned pointer is owned by the face and is destroyed with it.
    +   *
    +   *   For variation fonts, this string changes if you select a different
    +   *   instance, and you have to call `FT_Get_PostScript_Name` again to
    +   *   retrieve it.  FreeType follows Adobe TechNote #5902, 'Generating
    +   *   PostScript Names for Fonts Using OpenType Font Variations'.
    +   *
    +   *     https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html
    +   *
    +   *   [Since 2.9] Special PostScript names for named instances are only
    +   *   returned if the named instance is set with @FT_Set_Named_Instance (and
    +   *   the font has corresponding entries in its 'fvar' table).  If
    +   *   @FT_IS_VARIATION returns true, the algorithmically derived PostScript
    +   *   name is provided, not looking up special entries for named instances.
    +   */
    +  FT_EXPORT( const char* )
    +  FT_Get_Postscript_Name( FT_Face  face );
    +
    +
    +  /**************************************************************************
    +   *
        * @enum:
        *   FT_SUBGLYPH_FLAG_XXX
        *
    @@ -4348,13 +4362,6 @@
     
       /**************************************************************************
        *
    -   * @section:
    -   *   base_interface
    -   *
    -   */
    -
    -  /**************************************************************************
    -   *
        * @enum:
        *   FT_FSTYPE_XXX
        *
    @@ -4688,7 +4695,8 @@
        *
        * @description:
        *   This section contains various functions used to perform computations
    -   *   on 16.16 fixed-float numbers or 2d vectors.
    +   *   on 16.16 fixed-point numbers or 2D vectors.  FreeType does not use
    +   *   floating-point data types.
        *
        *   **Attention**: Most arithmetic functions take `FT_Long` as arguments.
        *   For historical reasons, FreeType was designed under the assumption
    @@ -4941,8 +4949,8 @@
        *
        */
     #define FREETYPE_MAJOR  2
    -#define FREETYPE_MINOR  12
    -#define FREETYPE_PATCH  1
    +#define FREETYPE_MINOR  13
    +#define FREETYPE_PATCH  0
     
     
       /**************************************************************************
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftadvanc.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Quick computation of advance widths (specification only).
      *
    - * Copyright (C) 2008-2022 by
    + * Copyright (C) 2008-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftbbox.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType exact bbox computation (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftbdf.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for accessing BDF-specific strings (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftbitmap.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType utility functions for bitmaps (specification).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftcid.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for accessing CID font information (specification).
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * Dereg Clegg and Michael Toftdal.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftcolor.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType's glyph color management (specification).
      *
    - * Copyright (C) 2018-2022 by
    + * Copyright (C) 2018-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -456,6 +456,9 @@
        *                                           &iterator ) );
        *     }
        *   ```
    +   *
    +   * @since:
    +   *   2.10
        */
       FT_EXPORT( FT_Bool )
       FT_Get_Color_Glyph_Layer( FT_Face            face,
    @@ -475,7 +478,7 @@
        *   extensions to the 'COLR' table, see
        *   'https://github.com/googlefonts/colr-gradients-spec'.
        *
    -   *   The enumeration values losely correspond with the format numbers of
    +   *   The enumeration values loosely correspond with the format numbers of
        *   the specification: FreeType always returns a fully specified 'Paint'
        *   structure for the 'Transform', 'Translate', 'Scale', 'Rotate', and
        *   'Skew' table types even though the specification has different formats
    @@ -489,9 +492,7 @@
        *   structures.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef enum  FT_PaintFormat_
       {
    @@ -521,9 +522,10 @@
        *
        * @description:
        *   This iterator object is needed for @FT_Get_Colorline_Stops.  It keeps
    -   *   state while iterating over the stops of an @FT_ColorLine,
    -   *   representing the `ColorLine` struct of the v1 extensions to 'COLR',
    -   *   see 'https://github.com/googlefonts/colr-gradients-spec'.
    +   *   state while iterating over the stops of an @FT_ColorLine, representing
    +   *   the `ColorLine` struct of the v1 extensions to 'COLR', see
    +   *   'https://github.com/googlefonts/colr-gradients-spec'.  Do not manually
    +   *   modify fields of this iterator.
        *
        * @fields:
        *   num_color_stops ::
    @@ -537,10 +539,12 @@
        *     An opaque pointer into 'COLR' table data.  Set by @FT_Get_Paint.
        *     Updated by @FT_Get_Colorline_Stops.
        *
    -   * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    +   *   read_variable ::
    +   *     A boolean keeping track of whether variable color lines are to be
    +   *     read.  Set by @FT_Get_Paint.
        *
    +   * @since:
    +   *   2.13
        */
       typedef struct  FT_ColorStopIterator_
       {
    @@ -549,6 +553,8 @@
     
         FT_Byte*  p;
     
    +    FT_Bool  read_variable;
    +
       } FT_ColorStopIterator;
     
     
    @@ -569,9 +575,7 @@
        *     Alpha transparency value multiplied with the value from 'CPAL'.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_ColorIndex_
       {
    @@ -592,19 +596,18 @@
        *
        * @fields:
        *   stop_offset ::
    -   *     The stop offset between 0 and 1 along the gradient.
    +   *     The stop offset along the gradient, expressed as a 16.16 fixed-point
    +   *     coordinate.
        *
        *   color ::
        *     The color information for this stop, see @FT_ColorIndex.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_ColorStop_
       {
    -    FT_F2Dot14     stop_offset;
    +    FT_Fixed       stop_offset;
         FT_ColorIndex  color;
     
       } FT_ColorStop;
    @@ -621,9 +624,7 @@
        *   It describes how the gradient fill continues at the other boundaries.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef enum  FT_PaintExtend_
       {
    @@ -653,9 +654,7 @@
        *     actual @FT_ColorStop's.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_ColorLine_
       {
    @@ -699,9 +698,7 @@
        *     y translation.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_Affine_23_
       {
    @@ -722,9 +719,7 @@
        *   'https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators'.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef enum  FT_Composite_Mode_
       {
    @@ -786,9 +781,7 @@
        *     to be provided.  Do not set this value.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_Opaque_Paint_
       {
    @@ -815,9 +808,7 @@
        *     The layer iterator that describes the layers of this paint.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintColrLayers_
       {
    @@ -842,9 +833,7 @@
        *     The color information for this solid paint, see @FT_ColorIndex.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintSolid_
       {
    @@ -883,9 +872,7 @@
        *     Otherwise equal to~p0.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintLinearGradient_
       {
    @@ -908,8 +895,7 @@
        *   A structure representing a `PaintRadialGradient` value of the 'COLR'
        *   v1 extensions, see
        *   'https://github.com/googlefonts/colr-gradients-spec'.  The glyph
    -   *   layer filled with this paint is drawn filled filled with a radial
    -   *   gradient.
    +   *   layer filled with this paint is drawn filled with a radial gradient.
        *
        * @fields:
        *   colorline ::
    @@ -933,9 +919,7 @@
        *     units represented as a 16.16 fixed-point value.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintRadialGradient_
       {
    @@ -983,9 +967,7 @@
        *     given counter-clockwise, starting from the (positive) y~axis.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintSweepGradient_
       {
    @@ -1016,9 +998,7 @@
        *     information that is filled with paint.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintGlyph_
       {
    @@ -1042,9 +1022,7 @@
        *     this paint.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintColrGlyph_
       {
    @@ -1070,9 +1048,7 @@
        *     16.16 fixed-point values.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintTransform_
       {
    @@ -1105,9 +1081,7 @@
        *     16.16 fixed-point value.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintTranslate_
       {
    @@ -1156,9 +1130,7 @@
        *     16.16 fixed-point value.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward-compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintScale_
       {
    @@ -1194,16 +1166,14 @@
        *
        *   center_x ::
        *     The x~coordinate of the pivot point of the rotation in font
    -   *     units) represented as a 16.16 fixed-point value.
    +   *     units represented as a 16.16 fixed-point value.
        *
        *   center_y ::
        *     The y~coordinate of the pivot point of the rotation in font
        *     units represented as a 16.16 fixed-point value.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
     
       typedef struct  FT_PaintRotate_
    @@ -1252,9 +1222,7 @@
        *     represented as a 16.16 fixed-point value.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintSkew_
       {
    @@ -1275,9 +1243,8 @@
        *   FT_PaintComposite
        *
        * @description:
    -   *   A structure representing a 'COLR'v1 `PaintComposite` paint table.
    -   *   Used for compositing two paints in a 'COLR' v1 directed acycling
    -   *   graph.
    +   *   A structure representing a 'COLR' v1 `PaintComposite` paint table.
    +   *   Used for compositing two paints in a 'COLR' v1 directed acyclic graph.
        *
        * @fields:
        *   source_paint ::
    @@ -1293,9 +1260,7 @@
        *     `source_paint` is composited onto.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_PaintComposite_
       {
    @@ -1339,9 +1304,7 @@
        *       * @FT_PaintColrGlyph
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_COLR_Paint_
       {
    @@ -1386,9 +1349,7 @@
        *     Do not output an initial root transform.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef enum  FT_Color_Root_Transform_
       {
    @@ -1429,9 +1390,7 @@
        *     fixed-point coordinates in 26.6 format.
        *
        * @since:
    -   *   2.12 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       typedef struct  FT_ClipBox_
       {
    @@ -1524,9 +1483,7 @@
        *   error, value~0 is returned also.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       FT_EXPORT( FT_Bool )
       FT_Get_Color_Glyph_Paint( FT_Face                  face,
    @@ -1568,9 +1525,7 @@
        *   and remove transforms configured using @FT_Set_Transform.
        *
        * @since:
    -   *   2.12 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       FT_EXPORT( FT_Bool )
       FT_Get_Color_Glyph_ClipBox( FT_Face      face,
    @@ -1617,9 +1572,7 @@
        *   object can not be retrieved or any other error occurs.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       FT_EXPORT( FT_Bool )
       FT_Get_Paint_Layers( FT_Face            face,
    @@ -1660,9 +1613,7 @@
        *   also.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       FT_EXPORT( FT_Bool )
       FT_Get_Colorline_Stops( FT_Face                face,
    @@ -1698,9 +1649,7 @@
        *   this paint or any other error occured.
        *
        * @since:
    -   *   2.11 -- **currently experimental only!**  There might be changes
    -   *   without retaining backward compatibility of both the API and ABI.
    -   *
    +   *   2.13
        */
       FT_EXPORT( FT_Bool )
       FT_Get_Paint( FT_Face         face,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for controlling driver modules (specification only).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -820,7 +820,6 @@
        *   2.5
        */
     
    -
       /**************************************************************************
        *
        * @property:
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fterrdef.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType error codes (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fterrors.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType error code handling (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -29,7 +29,7 @@
        *
        * @description:
        *   The header file `fterrors.h` (which is automatically included by
    -   *   `freetype.h` defines the handling of FreeType's enumeration
    +   *   `freetype.h`) defines the handling of FreeType's enumeration
        *   constants.  It can also be used to generate error message strings
        *   with a small macro trick explained below.
        *
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftfntfmt.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Support functions for font formats.
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftgasp.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Access of TrueType's 'gasp' table (specification).
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftglyph.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType convenience functions to handle glyphs (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -355,7 +355,7 @@
        *
        * @output:
        *   aglyph ::
    -   *     A handle to the glyph object.
    +   *     A handle to the glyph object.  `NULL` in case of error.
        *
        * @return:
        *   FreeType error code.  0~means success.
    @@ -385,7 +385,7 @@
        *
        * @output:
        *   target ::
    -   *     A handle to the target glyph object.  0~in case of error.
    +   *     A handle to the target glyph object.  `NULL` in case of error.
        *
        * @return:
        *   FreeType error code.  0~means success.
    @@ -413,7 +413,7 @@
        *
        *   delta ::
        *     A pointer to a 2d vector to apply.  Coordinates are expressed in
    -   *     1/64th of a pixel.
    +   *     1/64 of a pixel.
        *
        * @return:
        *   FreeType error code (if not 0, the glyph format is not scalable).
    @@ -500,7 +500,7 @@
        * @output:
        *   acbox ::
        *     The glyph coordinate bounding box.  Coordinates are expressed in
    -   *     1/64th of pixels if it is grid-fitted.
    +   *     1/64 of pixels if it is grid-fitted.
        *
        * @note:
        *   Coordinates are relative to the glyph origin, using the y~upwards
    @@ -671,7 +671,7 @@
        *
        * @input:
        *   glyph ::
    -   *     A handle to the target glyph object.
    +   *     A handle to the target glyph object.  Can be `NULL`.
        */
       FT_EXPORT( void )
       FT_Done_Glyph( FT_Glyph  glyph );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftgzip.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Gzip-compressed stream support.
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   FreeType glyph image formats and default raster interface
      *   (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftincrem.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType incremental loading (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftlcdfil.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   FreeType API for color filtering of subpixel bitmap glyphs
      *   (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -137,11 +137,11 @@
        *
        *   FT_LCD_FILTER_DEFAULT ::
        *     This is a beveled, normalized, and color-balanced five-tap filter
    -   *     with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256th units.
    +   *     with weights of [0x08 0x4D 0x56 0x4D 0x08] in 1/256 units.
        *
        *   FT_LCD_FILTER_LIGHT ::
        *     this is a boxy, normalized, and color-balanced three-tap filter with
    -   *     weights of [0x00 0x55 0x56 0x55 0x00] in 1/256th units.
    +   *     weights of [0x00 0x55 0x56 0x55 0x00] in 1/256 units.
        *
        *   FT_LCD_FILTER_LEGACY ::
        *   FT_LCD_FILTER_LEGACY1 ::
    @@ -226,7 +226,7 @@
        *
        *   weights ::
        *     A pointer to an array; the function copies the first five bytes and
    -   *     uses them to specify the filter weights in 1/256th units.
    +   *     uses them to specify the filter weights in 1/256 units.
        *
        * @return:
        *   FreeType error code.  0~means success.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftlist.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Generic list support for FreeType (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Additional debugging APIs.
      *
    - * Copyright (C) 2020-2022 by
    + * Copyright (C) 2020-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmac.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Additional Mac-specific API.
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 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 -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType Multiple Master font interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -398,6 +398,10 @@
        *   FreeType error code.  0~means success.
        *
        * @note:
    +   *   The design coordinates are 16.16 fractional values for TrueType GX and
    +   *   OpenType variation fonts.  For Adobe MM fonts, the values are
    +   *   integers.
    +   *
        *   [Since 2.8.1] To reset all axes to the default values, call the
        *   function with `num_coords` set to zero and `coords` set to `NULL`.
        *   [Since 2.9] 'Default values' means the currently selected named
    @@ -440,6 +444,11 @@
        * @return:
        *   FreeType error code.  0~means success.
        *
    +   * @note:
    +   *   The design coordinates are 16.16 fractional values for TrueType GX and
    +   *   OpenType variation fonts.  For Adobe MM fonts, the values are
    +   *   integers.
    +   *
        * @since:
        *   2.7.1
        */
    @@ -471,9 +480,9 @@
        *     the number of axes, use default values for the remaining axes.
        *
        *   coords ::
    -   *     The design coordinates array (each element must be between 0 and 1.0
    -   *     for Adobe MM fonts, and between -1.0 and 1.0 for TrueType GX and
    -   *     OpenType variation fonts).
    +   *     The design coordinates array.  Each element is a 16.16 fractional
    +   *     value and must be between 0 and 1.0 for Adobe MM fonts, and between
    +   *     -1.0 and 1.0 for TrueType GX and OpenType variation fonts.
        *
        * @return:
        *   FreeType error code.  0~means success.
    @@ -518,7 +527,7 @@
        *
        * @output:
        *   coords ::
    -   *     The normalized blend coordinates array.
    +   *     The normalized blend coordinates array (as 16.16 fractional values).
        *
        * @return:
        *   FreeType error code.  0~means success.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmodapi.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType modules public interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftmoderr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType module error offsets (specification).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Support for the FT_Outline type used to store glyph shapes of
      *   most scalable font formats (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftparams.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for possible FT_Parameter tags (specification only).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType renderer modules public interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsizes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType size objects management (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsnames.h	2023-10-06 05:33:33.000000000 +0000
    @@ -7,7 +7,7 @@
      *
      *   This is _not_ used to retrieve glyph names!
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftstroke.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType path stroker (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -293,7 +293,7 @@
        *
        *   miter_limit ::
        *     The maximum reciprocal sine of half-angle at the miter join,
    -   *     expressed as 16.16 fixed point value.
    +   *     expressed as 16.16 fixed-point value.
        *
        * @note:
        *   The `radius` is expressed in the same units as the outline
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   FreeType synthesizing code for emboldening and slanting
      *   (specification).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -68,10 +68,19 @@
       FT_EXPORT( void )
       FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );
     
    -  /* Slant an outline glyph to the right by about 12 degrees. */
    +  /* Slant an outline glyph to the right by about 12 degrees.              */
       FT_EXPORT( void )
       FT_GlyphSlot_Oblique( FT_GlyphSlot  slot );
     
    +  /* Slant an outline glyph by a given sine of an angle.  You can apply    */
    +  /* slant along either x- or y-axis by choosing a corresponding non-zero  */
    +  /* argument.  If both slants are non-zero, some affine transformation    */
    +  /* will result.                                                          */
    +  FT_EXPORT( void )
    +  FT_GlyphSlot_Slant( FT_GlyphSlot  slot,
    +                      FT_Fixed      xslant,
    +                      FT_Fixed      yslant );
    +
       /* */
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType low-level system interface definition (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -229,7 +229,8 @@
        *     A handle to the source stream.
        *
        *   offset ::
    -   *     The offset of read in stream (always from start).
    +   *     The offset from the start of the stream to seek to if this is a seek
    +   *     operation (see note).
        *
        *   buffer ::
        *     The address of the read buffer.
    @@ -241,8 +242,13 @@
        *   The number of bytes effectively read by the stream.
        *
        * @note:
    -   *   This function might be called to perform a seek or skip operation with
    -   *   a `count` of~0.  A non-zero return value then indicates an error.
    +   *   This function performs a seek *or* a read operation depending on the
    +   *   argument values.  If `count` is zero, the operation is a seek to
    +   *   `offset` bytes.  If `count` is >~0, the operation is a read of `count`
    +   *   bytes from the current position in the stream, and the `offset` value
    +   *   should be ignored.
    +   *
    +   *   For seek operations, a non-zero return value indicates an error.
        *
        */
       typedef unsigned long
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fttrigon.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType trigonometric functions (specification).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/fttypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType simple types definitions (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -45,7 +45,10 @@
        * @description:
        *   This section contains the basic data types defined by FreeType~2,
        *   ranging from simple scalar types to bitmap descriptors.  More
    -   *   font-specific structures are defined in a different section.
    +   *   font-specific structures are defined in a different section.  Note
    +   *   that FreeType does not use floating-point data types.  Fractional
    +   *   values are represented by fixed-point integers, with lower bits
    +   *   storing the fractional part.
        *
        * @order:
        *   FT_Byte
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/autohint.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level 'autohint' module-specific interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/cffotypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Basic OpenType/CFF object type definitions (specification).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/cfftypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Basic OpenType/CFF type definitions and interface (specification
      *   only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -315,7 +315,7 @@
         /* The normal stack then points to these values instead of the DICT   */
         /* because all other operators in Private DICT clear the stack.       */
         /* `blend_stack' could be cleared at each operator other than blend.  */
    -    /* Blended values are stored as 5-byte fixed point values.            */
    +    /* Blended values are stored as 5-byte fixed-point values.            */
     
         FT_Byte*  blend_stack;    /* base of stack allocation     */
         FT_Byte*  blend_top;      /* first empty slot             */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Compiler-specific macro definitions used internally by FreeType.
      *
    - * Copyright (C) 2020-2022 by
    + * Copyright (C) 2020-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -36,6 +36,19 @@
     #  endif
     #endif
     
    +  /* Newer compilers warn for fall-through case statements. */
    +#ifndef FALL_THROUGH
    +#  if ( defined( __STDC_VERSION__ ) && __STDC_VERSION__ > 201710L ) || \
    +      ( defined( __cplusplus ) && __cplusplus > 201402L )
    +#    define FALL_THROUGH  [[__fallthrough__]]
    +#  elif ( defined( __GNUC__ ) && __GNUC__ >= 7 )          || \
    +        ( defined( __clang__ ) && __clang_major__ >= 10 )
    +#    define FALL_THROUGH  __attribute__(( __fallthrough__ ))
    +#  else
    +#    define FALL_THROUGH  ( (void)0 )
    +#  endif
    +#endif
    +
       /*
        * When defining a macro that expands to a non-trivial C statement, use
        * FT_BEGIN_STMNT and FT_END_STMNT to enclose the macro's body.  This
    @@ -258,7 +271,7 @@
        * To export a variable, use `FT_EXPORT_VAR`.
        */
     
    -  /* See `freetype/config/compiler_macros.h` for the `FT_EXPORT` definition */
    +  /* See `freetype/config/public-macros.h` for the `FT_EXPORT` definition */
     #define FT_EXPORT_DEF( x )  FT_FUNCTION_DEFINITION( x )
     
       /*
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Arithmetic computations (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -278,6 +278,40 @@
                           FT_Long  c );
     
     
    +  /**************************************************************************
    +   *
    +   * @function:
    +   *   FT_MulAddFix
    +   *
    +   * @description:
    +   *   Compute `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`, where `s[n]` is
    +   *   usually a 16.16 scalar.
    +   *
    +   * @input:
    +   *   s ::
    +   *     The array of scalars.
    +   *   f ::
    +   *     The array of factors.
    +   *   count ::
    +   *     The number of entries in the array.
    +   *
    +   * @return:
    +   *   The result of `(s[0] * f[0] + s[1] * f[1] + ...) / 0x10000`.
    +   *
    +   * @note:
    +   *   This function is currently used for the scaled delta computation of
    +   *   variation stores.  It internally uses 64-bit data types when
    +   *   available, otherwise it emulates 64-bit math by using 32-bit
    +   *   operations, which produce a correct result but most likely at a slower
    +   *   performance in comparison to the implementation base on `int64_t`.
    +   *
    +   */
    +  FT_BASE( FT_Int32 )
    +  FT_MulAddFix( FT_Fixed*  s,
    +                FT_Int32*  f,
    +                FT_UInt    count );
    +
    +
       /*
        * A variant of FT_Matrix_Multiply which scales its result afterwards.  The
        * idea is that both `a' and `b' are scaled by factors of 10 so that the
    @@ -413,11 +447,11 @@
       extern __inline FT_Int32
       FT_MSB_i386( FT_UInt32  x );
     
    -#pragma aux FT_MSB_i386 =     \
    -  "bsr eax, eax"              \
    -  parm [eax] nomemory         \
    -  value [eax]                 \
    -  modify exact [eax] nomemory;
    +#pragma aux FT_MSB_i386 =             \
    +  "bsr eax, eax"                      \
    +  __parm [__eax] __nomemory           \
    +  __value [__eax]                     \
    +  __modify __exact [__eax] __nomemory;
     
     #define FT_MSB( x )  FT_MSB_i386( x )
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdebug.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Debugging and logging component (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType internal font driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftgloadr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph loader (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmemory.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType memory management macros (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -96,15 +96,15 @@
     
     #ifdef FT_DEBUG_MEMORY
     
    -  FT_BASE( const char* )  _ft_debug_file;
    -  FT_BASE( long )         _ft_debug_lineno;
    +  FT_BASE( const char* )  ft_debug_file_;
    +  FT_BASE( long )         ft_debug_lineno_;
     
    -#define FT_DEBUG_INNER( exp )  ( _ft_debug_file   = __FILE__, \
    -                                 _ft_debug_lineno = __LINE__, \
    +#define FT_DEBUG_INNER( exp )  ( ft_debug_file_   = __FILE__, \
    +                                 ft_debug_lineno_ = __LINE__, \
                                      (exp) )
     
    -#define FT_ASSIGNP_INNER( p, exp )  ( _ft_debug_file   = __FILE__, \
    -                                      _ft_debug_lineno = __LINE__, \
    +#define FT_ASSIGNP_INNER( p, exp )  ( ft_debug_file_   = __FILE__, \
    +                                      ft_debug_lineno_ = __LINE__, \
                                           FT_ASSIGNP( p, exp ) )
     
     #else /* !FT_DEBUG_MEMORY */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -0,0 +1,85 @@
    +/****************************************************************************
    + *
    + * ftmmtypes.h
    + *
    + *   OpenType Variations type definitions for internal use
    + *   with the multi-masters service (specification).
    + *
    + * Copyright (C) 2022-2023 by
    + * David Turner, Robert Wilhelm, Werner Lemberg, George Williams, and
    + * Dominik Röttsches.
    + *
    + * This file is part of the FreeType project, and may only be used,
    + * modified, and distributed under the terms of the FreeType project
    + * license, LICENSE.TXT.  By continuing to use, modify, or distribute
    + * this file you indicate that you have read the license and
    + * understand and accept it fully.
    + *
    + */
    +
    +
    +#ifndef FTMMTYPES_H_
    +#define FTMMTYPES_H_
    +
    +FT_BEGIN_HEADER
    +
    +
    +  typedef FT_Int32  FT_ItemVarDelta;
    +
    +  typedef struct  GX_ItemVarDataRec_
    +  {
    +    FT_UInt            itemCount;       /* number of delta sets per item    */
    +    FT_UInt            regionIdxCount;  /* number of region indices         */
    +    FT_UInt*           regionIndices;   /* array of `regionCount' indices;  */
    +                                        /* these index `varRegionList'      */
    +    FT_ItemVarDelta*   deltaSet;        /* array of `itemCount' deltas      */
    +                                        /* use `innerIndex' for this array  */
    +
    +  } GX_ItemVarDataRec, *GX_ItemVarData;
    +
    +
    +  /* contribution of one axis to a region */
    +  typedef struct  GX_AxisCoordsRec_
    +  {
    +    FT_Fixed  startCoord;
    +    FT_Fixed  peakCoord;      /* zero means no effect (factor = 1) */
    +    FT_Fixed  endCoord;
    +
    +  } GX_AxisCoordsRec, *GX_AxisCoords;
    +
    +
    +  typedef struct  GX_VarRegionRec_
    +  {
    +    GX_AxisCoords  axisList;               /* array of axisCount records */
    +
    +  } GX_VarRegionRec, *GX_VarRegion;
    +
    +
    +  /* item variation store */
    +  typedef struct  GX_ItemVarStoreRec_
    +  {
    +    FT_UInt         dataCount;
    +    GX_ItemVarData  varData;            /* array of dataCount records;     */
    +                                        /* use `outerIndex' for this array */
    +    FT_UShort     axisCount;
    +    FT_UInt       regionCount;          /* total number of regions defined */
    +    GX_VarRegion  varRegionList;
    +
    +  } GX_ItemVarStoreRec, *GX_ItemVarStore;
    +
    +
    +  typedef struct  GX_DeltaSetIdxMapRec_
    +  {
    +    FT_ULong  mapCount;
    +    FT_UInt*  outerIndex;               /* indices to item var data */
    +    FT_UInt*  innerIndex;               /* indices to delta set     */
    +
    +  } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
    +
    +
    +FT_END_HEADER
    +
    +#endif /* FTMMTYPES_H_ */
    +
    +
    +/* END */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftobjs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType private base classes (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftpsprop.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Get and set properties of PostScript drivers (specification).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftrfork.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Embedded resource forks accessor (specification).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * Masatake YAMATO and Redhat K.K.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftserv.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType services (specification only).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftstream.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Stream handling (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -238,42 +238,42 @@
     #define FT_NEXT_BYTE( buffer )         \
               ( (unsigned char)*buffer++ )
     
    -#define FT_NEXT_SHORT( buffer )                                   \
    -          ( (short)( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) ) )
    +#define FT_NEXT_SHORT( buffer )                        \
    +          ( buffer += 2, FT_PEEK_SHORT( buffer - 2 ) )
     
    -#define FT_NEXT_USHORT( buffer )                                            \
    -          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) ) )
    +#define FT_NEXT_USHORT( buffer )                        \
    +          ( buffer += 2, FT_PEEK_USHORT( buffer - 2 ) )
     
    -#define FT_NEXT_OFF3( buffer )                                  \
    -          ( (long)( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) ) )
    +#define FT_NEXT_OFF3( buffer )                        \
    +          ( buffer += 3, FT_PEEK_OFF3( buffer - 3 ) )
     
    -#define FT_NEXT_UOFF3( buffer )                                           \
    -          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) ) )
    +#define FT_NEXT_UOFF3( buffer )                        \
    +          ( buffer += 3, FT_PEEK_UOFF3( buffer - 3 ) )
     
    -#define FT_NEXT_LONG( buffer )                                  \
    -          ( (long)( buffer += 4, FT_PEEK_LONG( buffer - 4 ) ) )
    +#define FT_NEXT_LONG( buffer )                        \
    +          ( buffer += 4, FT_PEEK_LONG( buffer - 4 ) )
     
    -#define FT_NEXT_ULONG( buffer )                                           \
    -          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) ) )
    +#define FT_NEXT_ULONG( buffer )                        \
    +          ( buffer += 4, FT_PEEK_ULONG( buffer - 4 ) )
     
     
    -#define FT_NEXT_SHORT_LE( buffer )                                   \
    -          ( (short)( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) ) )
    +#define FT_NEXT_SHORT_LE( buffer )                        \
    +          ( buffer += 2, FT_PEEK_SHORT_LE( buffer - 2 ) )
     
    -#define FT_NEXT_USHORT_LE( buffer )                                            \
    -          ( (unsigned short)( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) ) )
    +#define FT_NEXT_USHORT_LE( buffer )                        \
    +          ( buffer += 2, FT_PEEK_USHORT_LE( buffer - 2 ) )
     
    -#define FT_NEXT_OFF3_LE( buffer )                                  \
    -          ( (long)( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) ) )
    +#define FT_NEXT_OFF3_LE( buffer )                        \
    +          ( buffer += 3, FT_PEEK_OFF3_LE( buffer - 3 ) )
     
    -#define FT_NEXT_UOFF3_LE( buffer )                                           \
    -          ( (unsigned long)( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) ) )
    +#define FT_NEXT_UOFF3_LE( buffer )                        \
    +          ( buffer += 3, FT_PEEK_UOFF3_LE( buffer - 3 ) )
     
    -#define FT_NEXT_LONG_LE( buffer )                                  \
    -          ( (long)( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) ) )
    +#define FT_NEXT_LONG_LE( buffer )                        \
    +          ( buffer += 4, FT_PEEK_LONG_LE( buffer - 4 ) )
     
    -#define FT_NEXT_ULONG_LE( buffer )                                           \
    -          ( (unsigned long)( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) ) )
    +#define FT_NEXT_ULONG_LE( buffer )                        \
    +          ( buffer += 4, FT_PEEK_ULONG_LE( buffer - 4 ) )
     
     
       /**************************************************************************
    @@ -307,17 +307,17 @@
     
     #define FT_GET_CHAR()       FT_GET_MACRO( FT_Stream_GetByte, FT_Char )
     #define FT_GET_BYTE()       FT_GET_MACRO( FT_Stream_GetByte, FT_Byte )
    -#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetUShort, FT_Short )
    -#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetUShort, FT_UShort )
    -#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetUOffset, FT_ULong )
    -#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetULong, FT_Long )
    -#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
    -#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetULong, FT_ULong )
    -
    -#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Short )
    -#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UShort )
    -#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetULongLE, FT_Long )
    -#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
    +#define FT_GET_SHORT()      FT_GET_MACRO( FT_Stream_GetUShort, FT_Int16 )
    +#define FT_GET_USHORT()     FT_GET_MACRO( FT_Stream_GetUShort, FT_UInt16 )
    +#define FT_GET_UOFF3()      FT_GET_MACRO( FT_Stream_GetUOffset, FT_UInt32 )
    +#define FT_GET_LONG()       FT_GET_MACRO( FT_Stream_GetULong, FT_Int32 )
    +#define FT_GET_ULONG()      FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
    +#define FT_GET_TAG4()       FT_GET_MACRO( FT_Stream_GetULong, FT_UInt32 )
    +
    +#define FT_GET_SHORT_LE()   FT_GET_MACRO( FT_Stream_GetUShortLE, FT_Int16 )
    +#define FT_GET_USHORT_LE()  FT_GET_MACRO( FT_Stream_GetUShortLE, FT_UInt16 )
    +#define FT_GET_LONG_LE()    FT_GET_MACRO( FT_Stream_GetULongLE, FT_Int32 )
    +#define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_UInt32 )
     #endif
     
     
    @@ -334,16 +334,16 @@
        */
     #define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadByte, FT_Byte, var )
     #define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadByte, FT_Char, var )
    -#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, FT_Short, var )
    -#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadUShort, FT_UShort, var )
    -#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadUOffset, FT_ULong, var )
    -#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadULong, FT_Long, var )
    -#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadULong, FT_ULong, var )
    -
    -#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Short, var )
    -#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UShort, var )
    -#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Long, var )
    -#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadULongLE, FT_ULong, var )
    +#define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, FT_Int16, var )
    +#define FT_READ_USHORT( var )     FT_READ_MACRO( FT_Stream_ReadUShort, FT_UInt16, var )
    +#define FT_READ_UOFF3( var )      FT_READ_MACRO( FT_Stream_ReadUOffset, FT_UInt32, var )
    +#define FT_READ_LONG( var )       FT_READ_MACRO( FT_Stream_ReadULong, FT_Int32, var )
    +#define FT_READ_ULONG( var )      FT_READ_MACRO( FT_Stream_ReadULong, FT_UInt32, var )
    +
    +#define FT_READ_SHORT_LE( var )   FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_Int16, var )
    +#define FT_READ_USHORT_LE( var )  FT_READ_MACRO( FT_Stream_ReadUShortLE, FT_UInt16, var )
    +#define FT_READ_LONG_LE( var )    FT_READ_MACRO( FT_Stream_ReadULongLE, FT_Int32, var )
    +#define FT_READ_ULONG_LE( var )   FT_READ_MACRO( FT_Stream_ReadULongLE, FT_UInt32, var )
     
     
     #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM
    @@ -459,23 +459,23 @@
       FT_Stream_GetByte( FT_Stream  stream );
     
       /* read a 16-bit big-endian unsigned integer from an entered frame */
    -  FT_BASE( FT_UShort )
    +  FT_BASE( FT_UInt16 )
       FT_Stream_GetUShort( FT_Stream  stream );
     
       /* read a 24-bit big-endian unsigned integer from an entered frame */
    -  FT_BASE( FT_ULong )
    +  FT_BASE( FT_UInt32 )
       FT_Stream_GetUOffset( FT_Stream  stream );
     
       /* read a 32-bit big-endian unsigned integer from an entered frame */
    -  FT_BASE( FT_ULong )
    +  FT_BASE( FT_UInt32 )
       FT_Stream_GetULong( FT_Stream  stream );
     
       /* read a 16-bit little-endian unsigned integer from an entered frame */
    -  FT_BASE( FT_UShort )
    +  FT_BASE( FT_UInt16 )
       FT_Stream_GetUShortLE( FT_Stream  stream );
     
       /* read a 32-bit little-endian unsigned integer from an entered frame */
    -  FT_BASE( FT_ULong )
    +  FT_BASE( FT_UInt32 )
       FT_Stream_GetULongLE( FT_Stream  stream );
     
     
    @@ -485,7 +485,7 @@
                           FT_Error*  error );
     
       /* read a 16-bit big-endian unsigned integer from a stream */
    -  FT_BASE( FT_UShort )
    +  FT_BASE( FT_UInt16 )
       FT_Stream_ReadUShort( FT_Stream  stream,
                             FT_Error*  error );
     
    @@ -495,17 +495,17 @@
                              FT_Error*  error );
     
       /* read a 32-bit big-endian integer from a stream */
    -  FT_BASE( FT_ULong )
    +  FT_BASE( FT_UInt32 )
       FT_Stream_ReadULong( FT_Stream  stream,
                            FT_Error*  error );
     
       /* read a 16-bit little-endian unsigned integer from a stream */
    -  FT_BASE( FT_UShort )
    +  FT_BASE( FT_UInt16 )
       FT_Stream_ReadUShortLE( FT_Stream  stream,
                               FT_Error*  error );
     
       /* read a 32-bit little-endian unsigned integer from a stream */
    -  FT_BASE( FT_ULong )
    +  FT_BASE( FT_UInt32 )
       FT_Stream_ReadULongLE( FT_Stream  stream,
                              FT_Error*  error );
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/fttrace.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Tracing handling (specification only).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftvalid.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType validation support (specification).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/psaux.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Auxiliary functions and data structures related to PostScript fonts
      *   (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -132,9 +132,6 @@
        *   max_elems ::
        *     The maximum number of elements in table.
        *
    -   *   num_elems ::
    -   *     The current number of elements in table.
    -   *
        *   elements ::
        *     A table of element addresses within the block.
        *
    @@ -155,7 +152,6 @@
         FT_ULong           init;
     
         FT_Int             max_elems;
    -    FT_Int             num_elems;
         FT_Byte**          elements;       /* addresses of table elements */
         FT_UInt*           lengths;        /* lengths of table elements   */
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/pshints.h	2023-10-06 05:33:33.000000000 +0000
    @@ -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-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -294,7 +294,7 @@
        *
        * @note:
        *   On input, all points within the outline are in font coordinates. On
    -   *   output, they are in 1/64th of pixels.
    +   *   output, they are in 1/64 of pixels.
        *
        *   The scaling transformation is taken from the 'globals' object which
        *   must correspond to the same font as the glyph.
    @@ -607,7 +607,7 @@
        *
        * @note:
        *   On input, all points within the outline are in font coordinates. On
    -   *   output, they are in 1/64th of pixels.
    +   *   output, they are in 1/64 of pixels.
        *
        *   The scaling transformation is taken from the 'globals' object which
        *   must correspond to the same font than the glyph.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svbdf.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType BDF services (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcfftl.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType CFF tables loader service (specification).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svcid.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType CID font services (specification).
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * Derek Clegg and Michael Toftdal.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svfntfmt.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType font format service (specification only).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgldict.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph dictionary services (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svgxval.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for validating TrueTypeGX/AAT tables (specification).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * Masatake YAMATO, Red Hat K.K.,
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svkern.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType Kerning service (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType services for metrics variations (specification).
      *
    - * Copyright (C) 2016-2022 by
    + * Copyright (C) 2016-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,8 +4,8 @@
      *
      *   The FreeType Multiple Masters and GX var services (specification).
      *
    - * Copyright (C) 2003-2022 by
    - * David Turner, Robert Wilhelm, and Werner Lemberg.
    + * Copyright (C) 2003-2023 by
    + * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
      *
      * This file is part of the FreeType project, and may only be used,
      * modified, and distributed under the terms of the FreeType project
    @@ -19,7 +19,9 @@
     #ifndef SVMM_H_
     #define SVMM_H_
     
    +#include 
     #include 
    +#include 
     
     
     FT_BEGIN_HEADER
    @@ -96,53 +98,94 @@
                                       FT_UInt*   len,
                                       FT_Fixed*  weight_vector );
     
    +  typedef FT_Error
    +  (*FT_Var_Load_Delta_Set_Idx_Map_Func)( FT_Face            face,
    +                                         FT_ULong           offset,
    +                                         GX_DeltaSetIdxMap  map,
    +                                         GX_ItemVarStore    itemStore,
    +                                         FT_ULong           table_len );
    +
    +  typedef FT_Error
    +  (*FT_Var_Load_Item_Var_Store_Func)( FT_Face          face,
    +                                      FT_ULong         offset,
    +                                      GX_ItemVarStore  itemStore );
    +
    +  typedef FT_ItemVarDelta
    +  (*FT_Var_Get_Item_Delta_Func)( FT_Face          face,
    +                                 GX_ItemVarStore  itemStore,
    +                                 FT_UInt          outerIndex,
    +                                 FT_UInt          innerIndex );
    +
    +  typedef void
    +  (*FT_Var_Done_Item_Var_Store_Func)( FT_Face          face,
    +                                      GX_ItemVarStore  itemStore );
    +
    +  typedef void
    +  (*FT_Var_Done_Delta_Set_Idx_Map_Func)( FT_Face            face,
    +                                         GX_DeltaSetIdxMap  deltaSetIdxMap );
    +
     
       FT_DEFINE_SERVICE( MultiMasters )
       {
    -    FT_Get_MM_Func               get_mm;
    -    FT_Set_MM_Design_Func        set_mm_design;
    -    FT_Set_MM_Blend_Func         set_mm_blend;
    -    FT_Get_MM_Blend_Func         get_mm_blend;
    -    FT_Get_MM_Var_Func           get_mm_var;
    -    FT_Set_Var_Design_Func       set_var_design;
    -    FT_Get_Var_Design_Func       get_var_design;
    -    FT_Set_Instance_Func         set_instance;
    -    FT_Set_MM_WeightVector_Func  set_mm_weightvector;
    -    FT_Get_MM_WeightVector_Func  get_mm_weightvector;
    +    FT_Get_MM_Func                        get_mm;
    +    FT_Set_MM_Design_Func                 set_mm_design;
    +    FT_Set_MM_Blend_Func                  set_mm_blend;
    +    FT_Get_MM_Blend_Func                  get_mm_blend;
    +    FT_Get_MM_Var_Func                    get_mm_var;
    +    FT_Set_Var_Design_Func                set_var_design;
    +    FT_Get_Var_Design_Func                get_var_design;
    +    FT_Set_Instance_Func                  set_instance;
    +    FT_Set_MM_WeightVector_Func           set_mm_weightvector;
    +    FT_Get_MM_WeightVector_Func           get_mm_weightvector;
     
         /* for internal use; only needed for code sharing between modules */
    -    FT_Get_Var_Blend_Func  get_var_blend;
    -    FT_Done_Blend_Func     done_blend;
    +    FT_Var_Load_Delta_Set_Idx_Map_Func    load_delta_set_idx_map;
    +    FT_Var_Load_Item_Var_Store_Func       load_item_var_store;
    +    FT_Var_Get_Item_Delta_Func            get_item_delta;
    +    FT_Var_Done_Item_Var_Store_Func       done_item_var_store;
    +    FT_Var_Done_Delta_Set_Idx_Map_Func    done_delta_set_idx_map;
    +    FT_Get_Var_Blend_Func                 get_var_blend;
    +    FT_Done_Blend_Func                    done_blend;
       };
     
     
    -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,            \
    -                                           get_mm_,           \
    -                                           set_mm_design_,    \
    -                                           set_mm_blend_,     \
    -                                           get_mm_blend_,     \
    -                                           get_mm_var_,       \
    -                                           set_var_design_,   \
    -                                           get_var_design_,   \
    -                                           set_instance_,     \
    -                                           set_weightvector_, \
    -                                           get_weightvector_, \
    -                                           get_var_blend_,    \
    -                                           done_blend_ )      \
    -  static const FT_Service_MultiMastersRec  class_ =           \
    -  {                                                           \
    -    get_mm_,                                                  \
    -    set_mm_design_,                                           \
    -    set_mm_blend_,                                            \
    -    get_mm_blend_,                                            \
    -    get_mm_var_,                                              \
    -    set_var_design_,                                          \
    -    get_var_design_,                                          \
    -    set_instance_,                                            \
    -    set_weightvector_,                                        \
    -    get_weightvector_,                                        \
    -    get_var_blend_,                                           \
    -    done_blend_                                               \
    +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                  \
    +                                           get_mm_,                 \
    +                                           set_mm_design_,          \
    +                                           set_mm_blend_,           \
    +                                           get_mm_blend_,           \
    +                                           get_mm_var_,             \
    +                                           set_var_design_,         \
    +                                           get_var_design_,         \
    +                                           set_instance_,           \
    +                                           set_weightvector_,       \
    +                                           get_weightvector_,       \
    +                                           load_delta_set_idx_map_, \
    +                                           load_item_var_store_,    \
    +                                           get_item_delta_,         \
    +                                           done_item_var_store_,    \
    +                                           done_delta_set_idx_map_, \
    +                                           get_var_blend_,          \
    +                                           done_blend_ )            \
    +  static const FT_Service_MultiMastersRec  class_ =                 \
    +  {                                                                 \
    +    get_mm_,                                                        \
    +    set_mm_design_,                                                 \
    +    set_mm_blend_,                                                  \
    +    get_mm_blend_,                                                  \
    +    get_mm_var_,                                                    \
    +    set_var_design_,                                                \
    +    get_var_design_,                                                \
    +    set_instance_,                                                  \
    +    set_weightvector_,                                              \
    +    get_weightvector_,                                              \
    +    load_delta_set_idx_map_,                                        \
    +    load_item_var_store_,                                           \
    +    get_item_delta_,                                                \
    +    done_item_var_store_,                                           \
    +    done_delta_set_idx_map_,                                        \
    +    get_var_blend_,                                                 \
    +    done_blend_                                                     \
       };
     
       /* */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svotval.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType OpenType validation service (specification).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpfr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Internal PFR service functions (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpostnm.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType PostScript name services (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svprop.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType property service (specification).
      *
    - * Copyright (C) 2012-2022 by
    + * Copyright (C) 2012-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType PostScript charmap service (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpsinfo.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType PostScript info service (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svsfnt.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType SFNT table loading service (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttcmap.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType TrueType/sfnt cmap extra information service.
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * Masatake YAMATO, Redhat K.K.,
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svtteng.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType TrueType engine query service (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svttglyf.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType TrueType glyph service.
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * David Turner.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svwinfnt.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType Windows FNT/FONT service (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/sfnt.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level 'sfnt' driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/svginterface.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Interface of ot-svg module (specification only).
      *
    - * Copyright (C) 2022 by
    + * Copyright (C) 2022-2023 by
      * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Basic Type1/Type2 type definitions and interface (specification
      *   only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -172,8 +172,8 @@
       {
         FT_Bool        IsCIDFont;
         FT_BBox        FontBBox;
    -    FT_Fixed       Ascender;
    -    FT_Fixed       Descender;
    +    FT_Fixed       Ascender;     /* optional, mind the zero */
    +    FT_Fixed       Descender;    /* optional, mind the zero */
         AFM_TrackKern  TrackKerns;   /* free if non-NULL */
         FT_UInt        NumTrackKern;
         AFM_KernPair   KernPairs;    /* free if non-NULL */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Basic SFNT/TrueType type definitions and interface (specification
      *   only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/internal/wofftypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Basic WOFF/WOFF2 type definitions and interface (specification
      *   only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/otsvg.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Interface for OT-SVG support related things (specification).
      *
    - * Copyright (C) 2022 by
    + * Copyright (C) 2022-2023 by
      * David Turner, Robert Wilhelm, Werner Lemberg, and Moazin Khatti.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/t1tables.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Basic Type 1/Type 2 tables definitions and interface (specification
      *   only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/ttnameid.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType name ID definitions (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/tttables.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Basic SFNT/TrueType tables definitions and interface
      *   (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -424,8 +424,8 @@
     
         /* only version 5 and higher: */
     
    -    FT_UShort  usLowerOpticalPointSize;       /* in twips (1/20th points) */
    -    FT_UShort  usUpperOpticalPointSize;       /* in twips (1/20th points) */
    +    FT_UShort  usLowerOpticalPointSize;       /* in twips (1/20 points) */
    +    FT_UShort  usUpperOpticalPointSize;       /* in twips (1/20 points) */
     
       } TT_OS2;
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/freetype/tttags.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Tags for TrueType and OpenType tables (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/ft2build.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/ft2build.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/include/ft2build.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/include/ft2build.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType 2 build and setup macros.
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.c	2023-10-06 05:33:33.000000000 +0000
    @@ -7,7 +7,7 @@
      *
      *   Auto-fitter data for blue strings (body).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.cin	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter data for blue strings (body).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat	2023-10-06 05:33:33.000000000 +0000
    @@ -2,7 +2,7 @@
     //
     //   Auto-fitter data for blue strings.
     //
    -// Copyright (C) 2013-2022 by
    +// Copyright (C) 2013-2023 by
     // David Turner, Robert Wilhelm, and Werner Lemberg.
     //
     // This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.h	2023-10-06 05:33:33.000000000 +0000
    @@ -7,7 +7,7 @@
      *
      *   Auto-fitter data for blue strings (specification).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afblue.hin	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter data for blue strings (specification).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter hinting routines for CJK writing system (body).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -650,7 +650,7 @@
           af_cjk_metrics_check_digits( metrics, face );
         }
     
    -    FT_Set_Charmap( face, oldmap );
    +    face->charmap = oldmap;
         return FT_Err_Ok;
       }
     
    @@ -741,9 +741,11 @@
                         ( dim == AF_DIMENSION_HORZ ) ? 'H' : 'V',
                         nn, blue->ref.org, blue->shoot.org ));
             FT_TRACE5(( "     ref:   cur=%.2f fit=%.2f\n",
    -                    blue->ref.cur / 64.0, blue->ref.fit / 64.0 ));
    +                    (double)blue->ref.cur / 64,
    +                    (double)blue->ref.fit / 64 ));
             FT_TRACE5(( "     shoot: cur=%.2f fit=%.2f\n",
    -                    blue->shoot.cur / 64.0, blue->shoot.fit / 64.0 ));
    +                    (double)blue->shoot.cur / 64,
    +                    (double)blue->shoot.fit / 64 ));
     
             blue->flags |= AF_CJK_BLUE_ACTIVE;
           }
    @@ -1044,7 +1046,7 @@
         {
           AF_Edge  found = NULL;
           FT_Pos   best  = 0xFFFFU;
    -      FT_Int   ee;
    +      FT_UInt  ee;
     
     
           /* look for an edge corresponding to the segment */
    @@ -1629,8 +1631,10 @@
         FT_TRACE5(( "  CJKLINK: edge %ld @%d (opos=%.2f) linked to %.2f,"
                     " dist was %.2f, now %.2f\n",
                     stem_edge - hints->axis[dim].edges, stem_edge->fpos,
    -                stem_edge->opos / 64.0, stem_edge->pos / 64.0,
    -                dist / 64.0, fitted_width / 64.0 ));
    +                (double)stem_edge->opos / 64,
    +                (double)stem_edge->pos / 64,
    +                (double)dist / 64,
    +                (double)fitted_width / 64 ));
       }
     
     
    @@ -1850,8 +1854,8 @@
     #ifdef FT_DEBUG_LEVEL_TRACE
             FT_TRACE5(( "  CJKBLUE: edge %ld @%d (opos=%.2f) snapped to %.2f,"
                         " was %.2f\n",
    -                    edge1 - edges, edge1->fpos, edge1->opos / 64.0,
    -                    blue->fit / 64.0, edge1->pos / 64.0 ));
    +                    edge1 - edges, edge1->fpos, (double)edge1->opos / 64,
    +                    (double)blue->fit / 64, (double)edge1->pos / 64 ));
     
             num_actions++;
     #endif
    @@ -2024,8 +2028,8 @@
     #if 0
           printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n",
                    edge - edges, edge2 - edges,
    -               ( edge->pos - edge->opos ) / 64.0,
    -               ( edge2->pos - edge2->opos ) / 64.0 );
    +               (double)( edge->pos - edge->opos ) / 64,
    +               (double)( edge2->pos - edge2->opos ) / 64 );
     #endif
     
           anchor = edge;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter hinting routines for CJK writing system (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afcover.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter coverages (specification only).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.c	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Auto-fitter dummy routines to be used if no hinting should be
      *   performed (body).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afdummy.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Auto-fitter dummy routines to be used if no hinting should be
      *   performed (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aferrors.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Autofitter error codes (specification only).
      *
    - * Copyright (C) 2005-2022 by
    + * Copyright (C) 2005-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter routines to compute global hinting values (body).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -129,13 +129,13 @@
         FT_Face     face        = globals->face;
         FT_CharMap  old_charmap = face->charmap;
         FT_UShort*  gstyles     = globals->glyph_styles;
    -    FT_UInt     ss;
    +    FT_UShort   ss;
    +    FT_UShort   dflt        = 0xFFFFU; /* a non-valid value */
         FT_UInt     i;
    -    FT_UInt     dflt        = ~0U; /* a non-valid value */
     
     
         /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */
    -    for ( i = 0; i < (FT_UInt)globals->glyph_count; i++ )
    +    for ( i = 0; i < globals->glyph_count; i++ )
           gstyles[i] = AF_STYLE_UNASSIGNED;
     
         error = FT_Select_Charmap( face, FT_ENCODING_UNICODE );
    @@ -168,8 +168,7 @@
            */
           if ( style_class->coverage == AF_COVERAGE_DEFAULT )
           {
    -        if ( (FT_UInt)style_class->script ==
    -             globals->module->default_script )
    +        if ( style_class->script == globals->module->default_script )
               dflt = ss;
     
             for ( range = script_class->script_uni_ranges;
    @@ -183,9 +182,9 @@
               gindex = FT_Get_Char_Index( face, charcode );
     
               if ( gindex != 0                                                &&
    -               gindex < (FT_ULong)globals->glyph_count                    &&
    +               gindex < globals->glyph_count                              &&
                    ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED )
    -            gstyles[gindex] = (FT_UShort)ss;
    +            gstyles[gindex] = ss;
     
               for (;;)
               {
    @@ -194,9 +193,9 @@
                 if ( gindex == 0 || charcode > range->last )
                   break;
     
    -            if ( gindex < (FT_ULong)globals->glyph_count                    &&
    +            if ( gindex < globals->glyph_count                              &&
                      ( gstyles[gindex] & AF_STYLE_MASK ) == AF_STYLE_UNASSIGNED )
    -              gstyles[gindex] = (FT_UShort)ss;
    +              gstyles[gindex] = ss;
               }
             }
     
    @@ -211,9 +210,9 @@
     
               gindex = FT_Get_Char_Index( face, charcode );
     
    -          if ( gindex != 0                                          &&
    -               gindex < (FT_ULong)globals->glyph_count              &&
    -               ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss )
    +          if ( gindex != 0                               &&
    +               gindex < globals->glyph_count             &&
    +               ( gstyles[gindex] & AF_STYLE_MASK ) == ss )
                 gstyles[gindex] |= AF_NONBASE;
     
               for (;;)
    @@ -223,8 +222,8 @@
                 if ( gindex == 0 || charcode > range->last )
                   break;
     
    -            if ( gindex < (FT_ULong)globals->glyph_count              &&
    -                 ( gstyles[gindex] & AF_STYLE_MASK ) == (FT_UShort)ss )
    +            if ( gindex < globals->glyph_count             &&
    +                 ( gstyles[gindex] & AF_STYLE_MASK ) == ss )
                   gstyles[gindex] |= AF_NONBASE;
               }
             }
    @@ -255,7 +254,7 @@
           FT_UInt  gindex = FT_Get_Char_Index( face, i );
     
     
    -      if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count )
    +      if ( gindex != 0 && gindex < globals->glyph_count )
             gstyles[gindex] |= AF_DIGIT;
         }
     
    @@ -266,7 +265,7 @@
          */
         if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED )
         {
    -      FT_Long  nn;
    +      FT_UInt  nn;
     
     
           for ( nn = 0; nn < globals->glyph_count; nn++ )
    @@ -290,7 +289,7 @@
         {
           AF_StyleClass  style_class = af_style_classes[ss];
           FT_UInt        count       = 0;
    -      FT_Long        idx;
    +      FT_UInt        idx;
     
     
           FT_TRACE4(( "%s:\n", af_style_names[style_class->style] ));
    @@ -302,7 +301,7 @@
               if ( !( count % 10 ) )
                 FT_TRACE4(( " " ));
     
    -          FT_TRACE4(( " %ld", idx ));
    +          FT_TRACE4(( " %d", idx ));
               count++;
     
               if ( !( count % 10 ) )
    @@ -318,7 +317,7 @@
     
     #endif /* FT_DEBUG_LEVEL_TRACE */
     
    -    FT_Set_Charmap( face, old_charmap );
    +    face->charmap = old_charmap;
         return error;
       }
     
    @@ -345,7 +344,7 @@
         FT_ZERO( &globals->metrics );
     
         globals->face                      = face;
    -    globals->glyph_count               = face->num_glyphs;
    +    globals->glyph_count               = (FT_UInt)face->num_glyphs;
         /* right after the globals structure come the glyph styles */
         globals->glyph_styles              = (FT_UShort*)( globals + 1 );
         globals->module                    = module;
    @@ -357,7 +356,7 @@
         globals->scale_down_factor         = 0;
     
     #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
    -    globals->hb_font = hb_ft_font_create( face, NULL );
    +    globals->hb_font = hb_ft_font_create_( face, NULL );
         globals->hb_buf  = hb_buffer_create();
     #endif
     
    @@ -429,7 +428,7 @@
         FT_Error  error = FT_Err_Ok;
     
     
    -    if ( gindex >= (FT_ULong)globals->glyph_count )
    +    if ( gindex >= globals->glyph_count )
         {
           error = FT_THROW( Invalid_Argument );
           goto Exit;
    @@ -501,7 +500,7 @@
       af_face_globals_is_digit( AF_FaceGlobals  globals,
                                 FT_UInt         gindex )
       {
    -    if ( gindex < (FT_ULong)globals->glyph_count )
    +    if ( gindex < globals->glyph_count )
           return FT_BOOL( globals->glyph_styles[gindex] & AF_DIGIT );
     
         return FT_BOOL( 0 );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Auto-fitter routines to compute global hinting values
      *   (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 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 @@
       typedef struct  AF_FaceGlobalsRec_
       {
         FT_Face          face;
    -    FT_Long          glyph_count;    /* same as face->num_glyphs */
    +    FT_UInt          glyph_count;    /* unsigned face->num_glyphs */
         FT_UShort*       glyph_styles;
     
     #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
    @@ -158,7 +158,7 @@
       FT_LOCAL( void )
       af_face_globals_free( AF_FaceGlobals  globals );
     
    -  FT_LOCAL_DEF( FT_Bool )
    +  FT_LOCAL( FT_Bool )
       af_face_globals_is_digit( AF_FaceGlobals  globals,
                                 FT_UInt         gindex );
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter hinting routines (body).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -151,9 +151,9 @@
         }
         else if ( axis->num_segments >= axis->max_segments )
         {
    -      FT_Int  old_max = axis->max_segments;
    -      FT_Int  new_max = old_max;
    -      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *segment ) );
    +      FT_UInt  old_max = axis->max_segments;
    +      FT_UInt  new_max = old_max;
    +      FT_UInt  big_max = FT_INT_MAX / sizeof ( *segment );
     
     
           if ( old_max >= big_max )
    @@ -193,7 +193,7 @@
       /* Get new edge for given axis, direction, and position, */
       /* without initializing the edge itself.                 */
     
    -  FT_LOCAL( FT_Error )
    +  FT_LOCAL_DEF( FT_Error )
       af_axis_hints_new_edge( AF_AxisHints  axis,
                               FT_Int        fpos,
                               AF_Direction  dir,
    @@ -216,9 +216,9 @@
         }
         else if ( axis->num_edges >= axis->max_edges )
         {
    -      FT_Int  old_max = axis->max_edges;
    -      FT_Int  new_max = old_max;
    -      FT_Int  big_max = (FT_Int)( FT_INT_MAX / sizeof ( *edge ) );
    +      FT_UInt  old_max = axis->max_edges;
    +      FT_UInt  new_max = old_max;
    +      FT_UInt  big_max = FT_INT_MAX / sizeof ( *edge );
     
     
           if ( old_max >= big_max )
    @@ -471,10 +471,10 @@
     
                     point->fx,
                     point->fy,
    -                point->ox / 64.0,
    -                point->oy / 64.0,
    -                point->x / 64.0,
    -                point->y / 64.0,
    +                (double)point->ox / 64,
    +                (double)point->oy / 64,
    +                (double)point->x / 64,
    +                (double)point->y / 64,
     
                     af_print_idx( buf5, af_get_strong_edge_index( hints,
                                                                   point->before,
    @@ -597,7 +597,7 @@
       FT_Error
       af_glyph_hints_get_num_segments( AF_GlyphHints  hints,
                                        FT_Int         dimension,
    -                                   FT_Int*        num_segments )
    +                                   FT_UInt*       num_segments )
       {
         AF_Dimension  dim;
         AF_AxisHints  axis;
    @@ -623,7 +623,7 @@
       FT_Error
       af_glyph_hints_get_segment_offset( AF_GlyphHints  hints,
                                          FT_Int         dimension,
    -                                     FT_Int         idx,
    +                                     FT_UInt        idx,
                                          FT_Pos        *offset,
                                          FT_Bool       *is_blue,
                                          FT_Pos        *blue_offset )
    @@ -640,7 +640,7 @@
     
         axis = &hints->axis[dim];
     
    -    if ( idx < 0 || idx >= axis->num_segments )
    +    if ( idx >= axis->num_segments )
           return FT_THROW( Invalid_Argument );
     
         seg      = &axis->segments[idx];
    @@ -692,13 +692,13 @@
           if ( dimension == AF_DIMENSION_HORZ )
             AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
                       "vertical",
    -                  65536.0 * 64.0 / hints->x_scale,
    -                  10.0 * hints->x_scale / 65536.0 / 64.0 ));
    +                  65536 * 64 / (double)hints->x_scale,
    +                  10 * (double)hints->x_scale / 65536 / 64 ));
           else
             AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n",
                       "horizontal",
    -                  65536.0 * 64.0 / hints->y_scale,
    -                  10.0 * hints->y_scale / 65536.0 / 64.0 ));
    +                  65536 * 64 / (double)hints->y_scale,
    +                  10 * (double)hints->y_scale / 65536 / 64 ));
     
           if ( axis->num_edges )
           {
    @@ -714,14 +714,14 @@
             AF_DUMP(( "  %5d  %7.2f  %5s  %4s  %5s"
                       "    %c   %7.2f  %7.2f  %11s\n",
                       AF_INDEX_NUM( edge, edges ),
    -                  (int)edge->opos / 64.0,
    +                  (double)(int)edge->opos / 64,
                       af_dir_str( (AF_Direction)edge->dir ),
                       af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ),
                       af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ),
     
                       edge->blue_edge ? 'y' : 'n',
    -                  edge->opos / 64.0,
    -                  edge->pos / 64.0,
    +                  (double)edge->opos / 64,
    +                  (double)edge->pos / 64,
                       af_edge_flags_to_string( edge->flags ) ));
           AF_DUMP(( "\n" ));
         }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afhints.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter hinting routines (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -21,8 +21,6 @@
     
     #include "aftypes.h"
     
    -#define xxAF_SORT_SEGMENTS
    -
     FT_BEGIN_HEADER
     
       /*
    @@ -310,15 +308,12 @@
     
       typedef struct  AF_AxisHintsRec_
       {
    -    FT_Int        num_segments; /* number of used segments      */
    -    FT_Int        max_segments; /* number of allocated segments */
    +    FT_UInt       num_segments; /* number of used segments      */
    +    FT_UInt       max_segments; /* number of allocated segments */
         AF_Segment    segments;     /* segments array               */
    -#ifdef AF_SORT_SEGMENTS
    -    FT_Int        mid_segments;
    -#endif
     
    -    FT_Int        num_edges;    /* number of used edges      */
    -    FT_Int        max_edges;    /* number of allocated edges */
    +    FT_UInt       num_edges;    /* number of used edges      */
    +    FT_UInt       max_edges;    /* number of allocated edges */
         AF_Edge       edges;        /* edges array               */
     
         AF_Direction  major_dir;    /* either vertical or horizontal */
    @@ -380,14 +375,14 @@
     #ifdef FT_DEBUG_AUTOFIT
     
     #define AF_HINTS_DO_HORIZONTAL( h )                                     \
    -          ( !_af_debug_disable_horz_hints                            && \
    +          ( !af_debug_disable_horz_hints_                            && \
                 !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_HORIZONTAL ) )
     
     #define AF_HINTS_DO_VERTICAL( h )                                     \
    -          ( !_af_debug_disable_vert_hints                          && \
    +          ( !af_debug_disable_vert_hints_                          && \
                 !AF_HINTS_TEST_SCALER( h, AF_SCALER_FLAG_NO_VERTICAL ) )
     
    -#define AF_HINTS_DO_BLUES( h )  ( !_af_debug_disable_blue_hints )
    +#define AF_HINTS_DO_BLUES( h )  ( !af_debug_disable_blue_hints_ )
     
     #else /* !FT_DEBUG_AUTOFIT */
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter hinting routines for Indic writing system (body).
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * Rahul Bhalerao , .
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -49,8 +49,7 @@
           af_cjk_metrics_check_digits( metrics, face );
         }
     
    -    FT_Set_Charmap( face, oldmap );
    -
    +    face->charmap = oldmap;
         return FT_Err_Ok;
       }
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afindic.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Auto-fitter hinting routines for Indic writing system
      *   (specification).
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * Rahul Bhalerao , .
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter hinting routines for latin writing system (body).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1043,7 +1043,7 @@
           AF_FaceGlobals  globals = metrics->root.globals;
           FT_UShort*      gstyles = globals->glyph_styles;
     
    -      FT_Long  i;
    +      FT_UInt  i;
     
     
           FT_TRACE5(( "no blue zones found:"
    @@ -1157,7 +1157,7 @@
         }
     
       Exit:
    -    FT_Set_Charmap( face, oldmap );
    +    face->charmap = oldmap;
         return error;
       }
     
    @@ -1275,8 +1275,8 @@
                   FT_TRACE5(( "                           "
                               " vertical scaling changed"
                               " from %.5f to %.5f (by %ld%%)\n",
    -                          scale / 65536.0,
    -                          new_scale / 65536.0,
    +                          (double)scale / 65536,
    +                          (double)new_scale / 65536,
                               ( fitted - scaled ) * 100 / scaled ));
                   FT_TRACE5(( "\n" ));
     
    @@ -1327,7 +1327,7 @@
     
           FT_TRACE5(( "  %ld scaled to %.2f\n",
                       width->org,
    -                  width->cur / 64.0 ));
    +                  (double)width->cur / 64 ));
         }
     
         FT_TRACE5(( "\n" ));
    @@ -1471,13 +1471,13 @@
             FT_TRACE5(( "  reference %d: %ld scaled to %.2f%s\n",
                         nn,
                         blue->ref.org,
    -                    blue->ref.fit / 64.0,
    +                    (double)blue->ref.fit / 64,
                         ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
                                                                : " (inactive)" ));
             FT_TRACE5(( "  overshoot %d: %ld scaled to %.2f%s\n",
                         nn,
                         blue->shoot.org,
    -                    blue->shoot.fit / 64.0,
    +                    (double)blue->shoot.fit / 64,
                         ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? ""
                                                                : " (inactive)" ));
           }
    @@ -2203,7 +2203,7 @@
         for ( seg = segments; seg < segment_limit; seg++ )
         {
           AF_Edge  found = NULL;
    -      FT_Int   ee;
    +      FT_UInt  ee;
     
     
           /* ignore too short segments, too wide ones, and, in this loop, */
    @@ -2277,7 +2277,7 @@
         for ( seg = segments; seg < segment_limit; seg++ )
         {
           AF_Edge  found = NULL;
    -      FT_Int   ee;
    +      FT_UInt  ee;
     
     
           if ( seg->dir != AF_DIR_NONE )
    @@ -2955,8 +2955,9 @@
     
         FT_TRACE5(( "  LINK: edge %ld (opos=%.2f) linked to %.2f,"
                     " dist was %.2f, now %.2f\n",
    -                stem_edge - hints->axis[dim].edges, stem_edge->opos / 64.0,
    -                stem_edge->pos / 64.0, dist / 64.0, fitted_width / 64.0 ));
    +                stem_edge - hints->axis[dim].edges,
    +                (double)stem_edge->opos / 64, (double)stem_edge->pos / 64,
    +                (double)dist / 64, (double)fitted_width / 64 ));
       }
     
     
    @@ -3079,13 +3080,15 @@
             if ( !anchor )
               FT_TRACE5(( "  BLUE_ANCHOR: edge %ld (opos=%.2f) snapped to %.2f,"
                           " was %.2f (anchor=edge %ld)\n",
    -                      edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
    -                      edge1->pos / 64.0, edge - edges ));
    +                      edge1 - edges,
    +                      (double)edge1->opos / 64, (double)blue->fit / 64,
    +                      (double)edge1->pos / 64, edge - edges ));
             else
               FT_TRACE5(( "  BLUE: edge %ld (opos=%.2f) snapped to %.2f,"
                           " was %.2f\n",
    -                      edge1 - edges, edge1->opos / 64.0, blue->fit / 64.0,
    -                      edge1->pos / 64.0 ));
    +                      edge1 - edges,
    +                      (double)edge1->opos / 64, (double)blue->fit / 64,
    +                      (double)edge1->pos / 64 ));
     
             num_actions++;
     #endif
    @@ -3201,9 +3204,9 @@
     
             FT_TRACE5(( "  ANCHOR: edge %ld (opos=%.2f) and %ld (opos=%.2f)"
                         " snapped to %.2f and %.2f\n",
    -                    edge - edges, edge->opos / 64.0,
    -                    edge2 - edges, edge2->opos / 64.0,
    -                    edge->pos / 64.0, edge2->pos / 64.0 ));
    +                    edge - edges, (double)edge->opos / 64,
    +                    edge2 - edges, (double)edge2->opos / 64,
    +                    (double)edge->pos / 64, (double)edge2->pos / 64 ));
     
             af_latin_align_linked_edge( hints, dim, edge, edge2 );
     
    @@ -3229,8 +3232,8 @@
             if ( edge2->flags & AF_EDGE_DONE )
             {
               FT_TRACE5(( "  ADJUST: edge %ld (pos=%.2f) moved to %.2f\n",
    -                      edge - edges, edge->pos / 64.0,
    -                      ( edge2->pos - cur_len ) / 64.0 ));
    +                      edge - edges, (double)edge->pos / 64,
    +                      (double)( edge2->pos - cur_len ) / 64 ));
     
               edge->pos = edge2->pos - cur_len;
             }
    @@ -3271,9 +3274,9 @@
     
               FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
                           " snapped to %.2f and %.2f\n",
    -                      edge - edges, edge->opos / 64.0,
    -                      edge2 - edges, edge2->opos / 64.0,
    -                      edge->pos / 64.0, edge2->pos / 64.0 ));
    +                      edge - edges, (double)edge->opos / 64,
    +                      edge2 - edges, (double)edge2->opos / 64,
    +                      (double)edge->pos / 64, (double)edge2->pos / 64 ));
             }
     
             else
    @@ -3302,9 +3305,9 @@
     
               FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
                           " snapped to %.2f and %.2f\n",
    -                      edge - edges, edge->opos / 64.0,
    -                      edge2 - edges, edge2->opos / 64.0,
    -                      edge->pos / 64.0, edge2->pos / 64.0 ));
    +                      edge - edges, (double)edge->opos / 64,
    +                      edge2 - edges, (double)edge2->opos / 64,
    +                      (double)edge->pos / 64, (double)edge2->pos / 64 ));
             }
     
     #ifdef FT_DEBUG_LEVEL_TRACE
    @@ -3325,8 +3328,8 @@
     #ifdef FT_DEBUG_LEVEL_TRACE
                 FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
                             edge - edges,
    -                        edge->pos / 64.0,
    -                        edge[-1].pos / 64.0 ));
    +                        (double)edge->pos / 64,
    +                        (double)edge[-1].pos / 64 ));
     
                 num_actions++;
     #endif
    @@ -3427,9 +3430,9 @@
               af_latin_align_serif_edge( hints, edge->serif, edge );
               FT_TRACE5(( "  SERIF: edge %ld (opos=%.2f) serif to %ld (opos=%.2f)"
                           " aligned to %.2f\n",
    -                      edge - edges, edge->opos / 64.0,
    -                      edge->serif - edges, edge->serif->opos / 64.0,
    -                      edge->pos / 64.0 ));
    +                      edge - edges, (double)edge->opos / 64,
    +                      edge->serif - edges, (double)edge->serif->opos / 64,
    +                      (double)edge->pos / 64 ));
             }
             else if ( !anchor )
             {
    @@ -3437,7 +3440,8 @@
               anchor    = edge;
               FT_TRACE5(( "  SERIF_ANCHOR: edge %ld (opos=%.2f)"
                           " snapped to %.2f\n",
    -                      edge-edges, edge->opos / 64.0, edge->pos / 64.0 ));
    +                      edge-edges,
    +                      (double)edge->opos / 64, (double)edge->pos / 64 ));
             }
             else
             {
    @@ -3465,9 +3469,9 @@
     
                 FT_TRACE5(( "  SERIF_LINK1: edge %ld (opos=%.2f) snapped to %.2f"
                             " from %ld (opos=%.2f)\n",
    -                        edge - edges, edge->opos / 64.0,
    -                        edge->pos / 64.0,
    -                        before - edges, before->opos / 64.0 ));
    +                        edge - edges, (double)edge->opos / 64,
    +                        (double)edge->pos / 64,
    +                        before - edges, (double)before->opos / 64 ));
               }
               else
               {
    @@ -3475,7 +3479,8 @@
                             ( ( edge->opos - anchor->opos + 16 ) & ~31 );
                 FT_TRACE5(( "  SERIF_LINK2: edge %ld (opos=%.2f)"
                             " snapped to %.2f\n",
    -                        edge - edges, edge->opos / 64.0, edge->pos / 64.0 ));
    +                        edge - edges,
    +                        (double)edge->opos / 64, (double)edge->pos / 64 ));
               }
             }
     
    @@ -3495,8 +3500,8 @@
     #ifdef FT_DEBUG_LEVEL_TRACE
                 FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
                             edge - edges,
    -                        edge->pos / 64.0,
    -                        edge[-1].pos / 64.0 ));
    +                        (double)edge->pos / 64,
    +                        (double)edge[-1].pos / 64 ));
     
                 num_actions++;
     #endif
    @@ -3516,8 +3521,8 @@
     #ifdef FT_DEBUG_LEVEL_TRACE
                 FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
                             edge - edges,
    -                        edge->pos / 64.0,
    -                        edge[1].pos / 64.0 ));
    +                        (double)edge->pos / 64,
    +                        (double)edge[1].pos / 64 ));
     
                 num_actions++;
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Auto-fitter hinting routines for latin writing system
      *   (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter glyph loading routines (body).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -229,9 +229,6 @@
         AF_WritingSystemClass  writing_system_class;
     
     
    -    if ( !size )
    -      return FT_THROW( Invalid_Size_Handle );
    -
         FT_ZERO( &scaler );
     
         if ( !size_internal->autohint_metrics.x_scale                          ||
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afloader.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter glyph loading routines (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -75,7 +75,7 @@
                             FT_UInt    gindex,
                             FT_Int32   load_flags );
     
    -  FT_LOCAL_DEF( FT_Fixed )
    +  FT_LOCAL( FT_Fixed )
       af_loader_compute_darkening( AF_Loader  loader,
                                    FT_Face    face,
                                    FT_Pos     standard_width );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter module implementation (body).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -43,14 +43,14 @@
     
     #endif
     
    -  int  _af_debug_disable_horz_hints;
    -  int  _af_debug_disable_vert_hints;
    -  int  _af_debug_disable_blue_hints;
    +  int  af_debug_disable_horz_hints_;
    +  int  af_debug_disable_vert_hints_;
    +  int  af_debug_disable_blue_hints_;
     
       /* we use a global object instead of a local one for debugging */
    -  static AF_GlyphHintsRec  _af_debug_hints_rec[1];
    +  static AF_GlyphHintsRec  af_debug_hints_rec_[1];
     
    -  void*  _af_debug_hints = _af_debug_hints_rec;
    +  void*  af_debug_hints_ = af_debug_hints_rec_;
     #endif
     
     #include 
    @@ -119,8 +119,8 @@
     
         if ( !ft_strcmp( property_name, "fallback-script" ) )
         {
    -      FT_UInt*  fallback_script;
    -      FT_UInt   ss;
    +      AF_Script*  fallback_script;
    +      FT_UInt     ss;
     
     
     #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
    @@ -128,7 +128,7 @@
             return FT_THROW( Invalid_Argument );
     #endif
     
    -      fallback_script = (FT_UInt*)value;
    +      fallback_script = (AF_Script*)value;
     
           /* We translate the fallback script to a fallback style that uses */
           /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its  */
    @@ -138,8 +138,8 @@
             AF_StyleClass  style_class = af_style_classes[ss];
     
     
    -        if ( (FT_UInt)style_class->script == *fallback_script &&
    -             style_class->coverage == AF_COVERAGE_DEFAULT     )
    +        if ( style_class->script   == *fallback_script    &&
    +             style_class->coverage == AF_COVERAGE_DEFAULT )
             {
               module->fallback_style = ss;
               break;
    @@ -157,7 +157,7 @@
         }
         else if ( !ft_strcmp( property_name, "default-script" ) )
         {
    -      FT_UInt*  default_script;
    +      AF_Script*  default_script;
     
     
     #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
    @@ -165,7 +165,7 @@
             return FT_THROW( Invalid_Argument );
     #endif
     
    -      default_script = (FT_UInt*)value;
    +      default_script = (AF_Script*)value;
     
           module->default_script = *default_script;
     
    @@ -291,8 +291,6 @@
       {
         FT_Error   error          = FT_Err_Ok;
         AF_Module  module         = (AF_Module)ft_module;
    -    FT_UInt    fallback_style = module->fallback_style;
    -    FT_UInt    default_script = module->default_script;
     
     
         if ( !ft_strcmp( property_name, "glyph-to-script-map" ) )
    @@ -309,9 +307,9 @@
         }
         else if ( !ft_strcmp( property_name, "fallback-script" ) )
         {
    -      FT_UInt*  val = (FT_UInt*)value;
    +      AF_Script*  val = (AF_Script*)value;
     
    -      AF_StyleClass  style_class = af_style_classes[fallback_style];
    +      AF_StyleClass  style_class = af_style_classes[module->fallback_style];
     
     
           *val = style_class->script;
    @@ -320,10 +318,10 @@
         }
         else if ( !ft_strcmp( property_name, "default-script" ) )
         {
    -      FT_UInt*  val = (FT_UInt*)value;
    +      AF_Script*  val = (AF_Script*)value;
     
     
    -      *val = default_script;
    +      *val = module->default_script;
     
           return error;
         }
    @@ -425,8 +423,8 @@
         FT_UNUSED( ft_module );
     
     #ifdef FT_DEBUG_AUTOFIT
    -    if ( _af_debug_hints_rec->memory )
    -      af_glyph_hints_done( _af_debug_hints_rec );
    +    if ( af_debug_hints_rec_->memory )
    +      af_glyph_hints_done( af_debug_hints_rec_ );
     #endif
       }
     
    @@ -445,7 +443,7 @@
     
         /* in debug mode, we use a global object that survives this routine */
     
    -    AF_GlyphHints  hints = _af_debug_hints_rec;
    +    AF_GlyphHints  hints = af_debug_hints_rec_;
         AF_LoaderRec   loader[1];
     
         FT_UNUSED( size );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter module implementation (specification).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -36,7 +36,7 @@
         FT_ModuleRec  root;
     
         FT_UInt       fallback_style;
    -    FT_UInt       default_script;
    +    AF_Script     default_script;
         FT_Bool       no_stem_darkening;
         FT_Int        darken_params[8];
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afranges.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter Unicode script ranges (body).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afranges.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter Unicode script ranges (specification).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afscript.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter scripts (specification only).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   HarfBuzz interface for accessing OpenType features (body).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   HarfBuzz interface for accessing OpenType features (specification).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -27,7 +27,7 @@
     
     #include 
     #include 
    -#include 
    +#include "ft-hb.h"
     
     #endif
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afstyles.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter styles (specification only).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/aftypes.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter types (specification only).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -57,10 +57,10 @@
     
     #ifdef FT_DEBUG_AUTOFIT
     
    -extern int    _af_debug_disable_horz_hints;
    -extern int    _af_debug_disable_vert_hints;
    -extern int    _af_debug_disable_blue_hints;
    -extern void*  _af_debug_hints;
    +extern int    af_debug_disable_horz_hints_;
    +extern int    af_debug_disable_vert_hints_;
    +extern int    af_debug_disable_blue_hints_;
    +extern void*  af_debug_hints_;
     
     #endif /* FT_DEBUG_AUTOFIT */
     
    @@ -119,13 +119,13 @@
     
       typedef struct  AF_ScalerRec_
       {
    -    FT_Face         face;        /* source font face                        */
    -    FT_Fixed        x_scale;     /* from font units to 1/64th device pixels */
    -    FT_Fixed        y_scale;     /* from font units to 1/64th device pixels */
    -    FT_Pos          x_delta;     /* in 1/64th device pixels                 */
    -    FT_Pos          y_delta;     /* in 1/64th device pixels                 */
    -    FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.     */
    -    FT_UInt32       flags;       /* additional control flags, see above     */
    +    FT_Face         face;        /* source font face                      */
    +    FT_Fixed        x_scale;     /* from font units to 1/64 device pixels */
    +    FT_Fixed        y_scale;     /* from font units to 1/64 device pixels */
    +    FT_Pos          x_delta;     /* in 1/64 device pixels                 */
    +    FT_Pos          y_delta;     /* in 1/64 device pixels                 */
    +    FT_Render_Mode  render_mode; /* monochrome, anti-aliased, LCD, etc.   */
    +    FT_UInt32       flags;       /* additional control flags, see above   */
     
       } AF_ScalerRec, *AF_Scaler;
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afws-decl.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter writing system declarations (specification only).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/autofit/afws-iter.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auto-fitter writing systems iterator (specification only).
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftadvanc.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Quick computation of advance widths (body).
      *
    - * Copyright (C) 2008-2022 by
    + * Copyright (C) 2008-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -23,7 +23,7 @@
     
     
       static FT_Error
    -  _ft_face_scale_advances( FT_Face    face,
    +  ft_face_scale_advances_( FT_Face    face,
                                FT_Fixed*  advances,
                                FT_UInt    count,
                                FT_Int32   flags )
    @@ -96,7 +96,7 @@
     
           error = func( face, gindex, 1, flags, padvance );
           if ( !error )
    -        return _ft_face_scale_advances( face, padvance, 1, flags );
    +        return ft_face_scale_advances_( face, padvance, 1, flags );
     
           if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
             return error;
    @@ -142,7 +142,7 @@
         {
           error = func( face, start, count, flags, padvances );
           if ( !error )
    -        return _ft_face_scale_advances( face, padvances, count, flags );
    +        return ft_face_scale_advances_( face, padvances, count, flags );
     
           if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
             return error;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftbase.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftbase.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftbase.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftbase.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Private functions used in the `base' module (specification).
      *
    - * Copyright (C) 2008-2022 by
    + * Copyright (C) 2008-2023 by
      * David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType bbox computation (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftbitmap.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType utility functions for bitmaps (body).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -66,11 +66,8 @@
       {
         FT_Memory  memory;
         FT_Error   error  = FT_Err_Ok;
    -
    -    FT_Int    pitch;
    -    FT_ULong  size;
    -
    -    FT_Int  source_pitch_sign, target_pitch_sign;
    +    FT_Int     pitch;
    +    FT_Int     flip;
     
     
         if ( !library )
    @@ -82,53 +79,29 @@
         if ( source == target )
           return FT_Err_Ok;
     
    -    source_pitch_sign = source->pitch < 0 ? -1 : 1;
    -    target_pitch_sign = target->pitch < 0 ? -1 : 1;
    +    flip = ( source->pitch < 0 && target->pitch > 0 ) ||
    +           ( source->pitch > 0 && target->pitch < 0 );
     
    -    if ( !source->buffer )
    -    {
    -      *target = *source;
    -      if ( source_pitch_sign != target_pitch_sign )
    -        target->pitch = -target->pitch;
    +    memory = library->memory;
    +    FT_FREE( target->buffer );
    +
    +    *target = *source;
    +
    +    if ( flip )
    +      target->pitch = -target->pitch;
     
    +    if ( !source->buffer )
           return FT_Err_Ok;
    -    }
     
    -    memory = library->memory;
         pitch  = source->pitch;
    -
         if ( pitch < 0 )
           pitch = -pitch;
    -    size = (FT_ULong)pitch * source->rows;
    -
    -    if ( target->buffer )
    -    {
    -      FT_Int    target_pitch = target->pitch;
    -      FT_ULong  target_size;
     
    -
    -      if ( target_pitch < 0 )
    -        target_pitch = -target_pitch;
    -      target_size = (FT_ULong)target_pitch * target->rows;
    -
    -      if ( target_size != size )
    -        FT_MEM_QREALLOC( target->buffer, target_size, size );
    -    }
    -    else
    -      FT_MEM_QALLOC( target->buffer, size );
    +    FT_MEM_QALLOC_MULT( target->buffer, target->rows, pitch );
     
         if ( !error )
         {
    -      unsigned char *p;
    -
    -
    -      p = target->buffer;
    -      *target = *source;
    -      target->buffer = p;
    -
    -      if ( source_pitch_sign == target_pitch_sign )
    -        FT_MEM_COPY( target->buffer, source->buffer, size );
    -      else
    +      if ( flip )
           {
             /* take care of bitmap flow */
             FT_UInt   i;
    @@ -146,6 +119,9 @@
               t -= pitch;
             }
           }
    +      else
    +        FT_MEM_COPY( target->buffer, source->buffer,
    +                     (FT_Long)source->rows * pitch );
         }
     
         return error;
    @@ -542,39 +518,31 @@
         case FT_PIXEL_MODE_LCD_V:
         case FT_PIXEL_MODE_BGRA:
           {
    -        FT_Int    pad, old_target_pitch, target_pitch;
    -        FT_ULong  old_size;
    +        FT_Int  width = (FT_Int)source->width;
    +        FT_Int  neg   = ( target->pitch == 0 && source->pitch < 0 ) ||
    +                          target->pitch  < 0;
     
     
    -        old_target_pitch = target->pitch;
    -        if ( old_target_pitch < 0 )
    -          old_target_pitch = -old_target_pitch;
    -
    -        old_size = target->rows * (FT_UInt)old_target_pitch;
    +        FT_Bitmap_Done( library, target );
     
             target->pixel_mode = FT_PIXEL_MODE_GRAY;
             target->rows       = source->rows;
             target->width      = source->width;
     
    -        pad = 0;
    -        if ( alignment > 0 )
    +        if ( alignment )
             {
    -          pad = (FT_Int)source->width % alignment;
    -          if ( pad != 0 )
    -            pad = alignment - pad;
    -        }
    +          FT_Int  rem = width % alignment;
     
    -        target_pitch = (FT_Int)source->width + pad;
     
    -        if ( target_pitch > 0                                               &&
    -             (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch )
    -          return FT_THROW( Invalid_Argument );
    +          if ( rem )
    +            width = alignment > 0 ? width - rem + alignment
    +                                  : width - rem - alignment;
    +        }
     
    -        if ( FT_QREALLOC( target->buffer,
    -                          old_size, target->rows * (FT_UInt)target_pitch ) )
    +        if ( FT_QALLOC_MULT( target->buffer, target->rows, width ) )
               return error;
     
    -        target->pitch = target->pitch < 0 ? -target_pitch : target_pitch;
    +        target->pitch = neg ? -width : width;
           }
           break;
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Arithmetic computations (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1085,4 +1085,71 @@
       }
     
     
    +  FT_BASE_DEF( FT_Int32 )
    +  FT_MulAddFix( FT_Fixed*  s,
    +                FT_Int32*  f,
    +                FT_UInt    count )
    +  {
    +    FT_UInt   i;
    +    FT_Int64  temp;
    +#ifndef FT_INT64
    +    FT_Int64  halfUnit;
    +#endif
    +
    +
    +#ifdef FT_INT64
    +    temp = 0;
    +
    +    for ( i = 0; i < count; ++i )
    +      temp += (FT_Int64)s[i] * f[i];
    +
    +    return ( temp + 0x8000 ) >> 16;
    +#else
    +    temp.hi = 0;
    +    temp.lo = 0;
    +
    +    for ( i = 0; i < count; ++i )
    +    {
    +      FT_Int64  multResult;
    +
    +      FT_Int     sign  = 1;
    +      FT_UInt32  carry = 0;
    +
    +      FT_UInt32  scalar;
    +      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_multo64( scalar, factor, &multResult );
    +
    +      if ( sign < 0 )
    +      {
    +        /* Emulated `FT_Int64` negation. */
    +        carry = ( multResult.lo == 0 );
    +
    +        multResult.lo = ~multResult.lo + 1;
    +        multResult.hi = ~multResult.hi + carry;
    +      }
    +
    +      FT_Add64( &temp, &multResult, &temp );
    +    }
    +
    +    /* Round value. */
    +    halfUnit.hi = 0;
    +    halfUnit.lo = 0x8000;
    +    FT_Add64( &temp, &halfUnit, &temp );
    +
    +    return (FT_Int32)( ( (FT_Int32)( temp.hi & 0xFFFF ) << 16 ) |
    +                                   ( temp.lo >> 16 )            );
    +
    +#endif /* !FT_INT64 */
    +
    +  }
    +
    +
     /* END */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftcid.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftcid.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftcid.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftcid.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for accessing CID font information.
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * Derek Clegg and Michael Toftdal.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftcolor.c	2023-10-06 05:33:33.000000000 +0000
    @@ -0,0 +1,156 @@
    +/****************************************************************************
    + *
    + * ftcolor.c
    + *
    + *   FreeType's glyph color management (body).
    + *
    + * Copyright (C) 2018-2023 by
    + * David Turner, Robert Wilhelm, and Werner Lemberg.
    + *
    + * This file is part of the FreeType project, and may only be used,
    + * modified, and distributed under the terms of the FreeType project
    + * license, LICENSE.TXT.  By continuing to use, modify, or distribute
    + * this file you indicate that you have read the license and
    + * understand and accept it fully.
    + *
    + */
    +
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +
    +#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
    +
    +  static
    +  const FT_Palette_Data  null_palette_data = { 0, NULL, NULL, 0, NULL };
    +
    +
    +  /* documentation is in ftcolor.h */
    +
    +  FT_EXPORT_DEF( FT_Error )
    +  FT_Palette_Data_Get( FT_Face           face,
    +                       FT_Palette_Data  *apalette_data )
    +  {
    +    if ( !face )
    +      return FT_THROW( Invalid_Face_Handle );
    +    if ( !apalette_data)
    +      return FT_THROW( Invalid_Argument );
    +
    +    if ( FT_IS_SFNT( face ) )
    +      *apalette_data = ( (TT_Face)face )->palette_data;
    +    else
    +      *apalette_data = null_palette_data;
    +
    +    return FT_Err_Ok;
    +  }
    +
    +
    +  /* documentation is in ftcolor.h */
    +
    +  FT_EXPORT_DEF( FT_Error )
    +  FT_Palette_Select( FT_Face     face,
    +                     FT_UShort   palette_index,
    +                     FT_Color*  *apalette )
    +  {
    +    FT_Error  error;
    +
    +    TT_Face       ttface;
    +    SFNT_Service  sfnt;
    +
    +
    +    if ( !face )
    +      return FT_THROW( Invalid_Face_Handle );
    +
    +    if ( !FT_IS_SFNT( face ) )
    +    {
    +      if ( apalette )
    +        *apalette = NULL;
    +
    +      return FT_Err_Ok;
    +    }
    +
    +    ttface = (TT_Face)face;
    +    sfnt   = (SFNT_Service)ttface->sfnt;
    +
    +    error = sfnt->set_palette( ttface, palette_index );
    +    if ( error )
    +      return error;
    +
    +    ttface->palette_index = palette_index;
    +
    +    if ( apalette )
    +      *apalette = ttface->palette;
    +
    +    return FT_Err_Ok;
    +  }
    +
    +
    +  /* documentation is in ftcolor.h */
    +
    +  FT_EXPORT_DEF( FT_Error )
    +  FT_Palette_Set_Foreground_Color( FT_Face   face,
    +                                   FT_Color  foreground_color )
    +  {
    +    TT_Face  ttface;
    +
    +
    +    if ( !face )
    +      return FT_THROW( Invalid_Face_Handle );
    +
    +    if ( !FT_IS_SFNT( face ) )
    +      return FT_Err_Ok;
    +
    +    ttface = (TT_Face)face;
    +
    +    ttface->foreground_color      = foreground_color;
    +    ttface->have_foreground_color = 1;
    +
    +    return FT_Err_Ok;
    +  }
    +
    +#else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
    +
    +  FT_EXPORT_DEF( FT_Error )
    +  FT_Palette_Data_Get( FT_Face           face,
    +                       FT_Palette_Data  *apalette_data )
    +  {
    +    FT_UNUSED( face );
    +    FT_UNUSED( apalette_data );
    +
    +
    +    return FT_THROW( Unimplemented_Feature );
    +  }
    +
    +
    +  FT_EXPORT_DEF( FT_Error )
    +  FT_Palette_Select( FT_Face     face,
    +                     FT_UShort   palette_index,
    +                     FT_Color*  *apalette )
    +  {
    +    FT_UNUSED( face );
    +    FT_UNUSED( palette_index );
    +    FT_UNUSED( apalette );
    +
    +
    +    return FT_THROW( Unimplemented_Feature );
    +  }
    +
    +
    +  FT_EXPORT_DEF( FT_Error )
    +  FT_Palette_Set_Foreground_Color( FT_Face   face,
    +                                   FT_Color  foreground_color )
    +  {
    +    FT_UNUSED( face );
    +    FT_UNUSED( foreground_color );
    +
    +
    +    return FT_THROW( Unimplemented_Feature );
    +  }
    +
    +#endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
    +
    +
    +/* END */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Memory debugger (body).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -35,8 +35,8 @@
     
     #include FT_CONFIG_STANDARD_LIBRARY_H
     
    -  FT_BASE_DEF( const char* )  _ft_debug_file   = NULL;
    -  FT_BASE_DEF( long )         _ft_debug_lineno = 0;
    +  FT_BASE_DEF( const char* )  ft_debug_file_   = NULL;
    +  FT_BASE_DEF( long )         ft_debug_lineno_ = 0;
     
       extern void
       FT_DumpMemory( FT_Memory  memory );
    @@ -415,8 +415,8 @@
     
         /* cast to FT_PtrDist first since void* can be larger */
         /* than FT_UInt32 and GCC 4.1.1 emits a warning       */
    -    hash  = (FT_UInt32)(FT_PtrDist)(void*)_ft_debug_file +
    -              (FT_UInt32)( 5 * _ft_debug_lineno );
    +    hash  = (FT_UInt32)(FT_PtrDist)(void*)ft_debug_file_ +
    +              (FT_UInt32)( 5 * ft_debug_lineno_ );
         pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS];
     
         for (;;)
    @@ -425,8 +425,8 @@
           if ( !node )
             break;
     
    -      if ( node->file_name == _ft_debug_file   &&
    -           node->line_no   == _ft_debug_lineno )
    +      if ( node->file_name == ft_debug_file_   &&
    +           node->line_no   == ft_debug_lineno_ )
             goto Exit;
     
           pnode = &node->link;
    @@ -437,8 +437,8 @@
           ft_mem_debug_panic(
             "not enough memory to perform memory debugging\n" );
     
    -    node->file_name = _ft_debug_file;
    -    node->line_no   = _ft_debug_lineno;
    +    node->file_name = ft_debug_file_;
    +    node->line_no   = ft_debug_lineno_;
     
         node->cur_blocks = 0;
         node->max_blocks = 0;
    @@ -495,7 +495,7 @@
                 "org=%s:%d new=%s:%d\n",
                 node->address, node->size,
                 FT_FILENAME( node->source->file_name ), node->source->line_no,
    -            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
    +            FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_ );
             }
           }
     
    @@ -582,7 +582,7 @@
                 "  Block was allocated at (%s:%ld)\n"
                 "  and released at (%s:%ld).",
                 address,
    -            FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
    +            FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_,
                 FT_FILENAME( node->source->file_name ), node->source->line_no,
                 FT_FILENAME( node->free_file_name ), node->free_line_no );
     
    @@ -604,8 +604,8 @@
               /* we simply invert the node's size to indicate that the node */
               /* was freed.                                                 */
               node->size           = -node->size;
    -          node->free_file_name = _ft_debug_file;
    -          node->free_line_no   = _ft_debug_lineno;
    +          node->free_file_name = ft_debug_file_;
    +          node->free_line_no   = ft_debug_lineno_;
             }
             else
             {
    @@ -627,7 +627,7 @@
             ft_mem_debug_panic(
               "trying to free unknown block at %p in (%s:%ld)\n",
               address,
    -          FT_FILENAME( _ft_debug_file ), _ft_debug_lineno );
    +          FT_FILENAME( ft_debug_file_ ), ft_debug_lineno_ );
         }
       }
     
    @@ -661,8 +661,8 @@
           table->alloc_count++;
         }
     
    -    _ft_debug_file   = "";
    -    _ft_debug_lineno = 0;
    +    ft_debug_file_   = "";
    +    ft_debug_lineno_ = 0;
     
         return (FT_Pointer)block;
       }
    @@ -677,8 +677,8 @@
     
         if ( !block )
           ft_mem_debug_panic( "trying to free NULL in (%s:%ld)",
    -                          FT_FILENAME( _ft_debug_file ),
    -                          _ft_debug_lineno );
    +                          FT_FILENAME( ft_debug_file_ ),
    +                          ft_debug_lineno_ );
     
         ft_mem_table_remove( table, (FT_Byte*)block, 0 );
     
    @@ -687,8 +687,8 @@
     
         table->alloc_count--;
     
    -    _ft_debug_file   = "";
    -    _ft_debug_lineno = 0;
    +    ft_debug_file_   = "";
    +    ft_debug_lineno_ = 0;
       }
     
     
    @@ -703,8 +703,8 @@
         FT_Pointer   new_block;
         FT_Long      delta;
     
    -    const char*  file_name = FT_FILENAME( _ft_debug_file );
    -    FT_Long      line_no   = _ft_debug_lineno;
    +    const char*  file_name = FT_FILENAME( ft_debug_file_ );
    +    FT_Long      line_no   = ft_debug_lineno_;
     
     
         /* unlikely, but possible */
    @@ -767,8 +767,8 @@
     
         ft_mem_table_remove( table, (FT_Byte*)block, delta );
     
    -    _ft_debug_file   = "";
    -    _ft_debug_lineno = 0;
    +    ft_debug_file_   = "";
    +    ft_debug_lineno_ = 0;
     
         if ( !table->keep_alive )
           ft_mem_table_free( table, block );
    @@ -874,7 +874,7 @@
       }
     
     
    -  static int
    +  FT_COMPARE_DEF( int )
       ft_mem_source_compare( const void*  p1,
                              const void*  p2 )
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftdebug.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Debugging and logging component (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftfntfmt.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType utility file for font formats (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftfstype.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType utility file to access FSType data (body).
      *
    - * Copyright (C) 2008-2022 by
    + * Copyright (C) 2008-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftgasp.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Access of TrueType's `gasp' table (body).
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftgloadr.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph loader (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -212,12 +212,12 @@
         FT_Outline*  current = &loader->current.outline;
         FT_Bool      adjust  = 0;
     
    -    FT_UInt      new_max, old_max;
    +    FT_UInt  new_max, old_max, min_new_max;
     
     
         error = FT_GlyphLoader_CreateExtra( loader );
         if ( error )
    -      return error;
    +      goto Exit;
     
         /* check points & tags */
         new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points +
    @@ -226,10 +226,18 @@
     
         if ( new_max > old_max )
         {
    -      new_max = FT_PAD_CEIL( new_max, 8 );
    +      if ( new_max > FT_OUTLINE_POINTS_MAX )
    +      {
    +        error = FT_THROW( Array_Too_Large );
    +        goto Exit;
    +      }
     
    +      min_new_max = old_max + ( old_max >> 1 );
    +      if ( new_max < min_new_max )
    +        new_max = min_new_max;
    +      new_max = FT_PAD_CEIL( new_max, 8 );
           if ( new_max > FT_OUTLINE_POINTS_MAX )
    -        return FT_THROW( Array_Too_Large );
    +        new_max = FT_OUTLINE_POINTS_MAX;
     
           if ( FT_RENEW_ARRAY( base->points, old_max, new_max ) ||
                FT_RENEW_ARRAY( base->tags,   old_max, new_max ) )
    @@ -254,7 +262,7 @@
     
         error = FT_GlyphLoader_CreateExtra( loader );
         if ( error )
    -      return error;
    +      goto Exit;
     
         /* check contours */
         old_max = loader->max_contours;
    @@ -262,10 +270,18 @@
                   n_contours;
         if ( new_max > old_max )
         {
    -      new_max = FT_PAD_CEIL( new_max, 4 );
    +      if ( new_max > FT_OUTLINE_CONTOURS_MAX )
    +      {
    +        error = FT_THROW( Array_Too_Large );
    +        goto Exit;
    +      }
     
    +      min_new_max = old_max + ( old_max >> 1 );
    +      if ( new_max < min_new_max )
    +        new_max = min_new_max;
    +      new_max = FT_PAD_CEIL( new_max, 4 );
           if ( new_max > FT_OUTLINE_CONTOURS_MAX )
    -        return FT_THROW( Array_Too_Large );
    +        new_max = FT_OUTLINE_CONTOURS_MAX;
     
           if ( FT_RENEW_ARRAY( base->contours, old_max, new_max ) )
             goto Exit;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftglyph.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType convenience functions to handle glyphs (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -682,7 +682,10 @@
       Exit2:
         /* if an error occurred, destroy the glyph */
         if ( error )
    +    {
           FT_Done_Glyph( glyph );
    +      *aglyph = NULL;
    +    }
         else
           *aglyph = glyph;
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftinit.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftinit.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftinit.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftinit.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType initialization layer (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftlcdfil.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType API for color filtering of subpixel bitmap glyphs (body).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftmac.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftmac.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftmac.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftmac.c	2023-10-06 05:33:33.000000000 +0000
    @@ -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-2022 by
    + * Copyright (C) 1996-2023 by
      * Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -67,6 +67,7 @@
     
     #include 
     #include 
    +#include 
     #include 
     #include "ftbase.h"
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftmm.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftmm.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftmm.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftmm.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Multiple Master font support (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType private base classes (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -508,7 +508,7 @@
     
         case FT_PIXEL_MODE_LCD_V:
           height *= 3;
    -      /* fall through */
    +      FALL_THROUGH;
     
         case FT_PIXEL_MODE_GRAY:
         default:
    @@ -605,7 +605,7 @@
     
     
             FT_FREE( doc->svg_document );
    -        slot->internal->load_flags &= ~FT_GLYPH_OWN_GZIP_SVG;
    +        slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG;
           }
         }
     #endif
    @@ -631,8 +631,9 @@
     #ifdef FT_CONFIG_OPTION_SVG
         if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
         {
    -      /* free memory in case SVG was there */
    -      if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
    +      /* Free memory in case SVG was there.                          */
    +      /* `slot->internal` might be NULL in out-of-memory situations. */
    +      if ( slot->internal && slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
           {
             FT_SVG_Document  doc = (FT_SVG_Document)slot->other;
     
    @@ -1184,28 +1185,34 @@
                     pixel_modes[slot->bitmap.pixel_mode],
                     slot->bitmap.pixel_mode ));
         FT_TRACE5(( "\n" ));
    -    FT_TRACE5(( "  x advance: %f\n", slot->advance.x / 64.0 ));
    -    FT_TRACE5(( "  y advance: %f\n", slot->advance.y / 64.0 ));
    +    FT_TRACE5(( "  x advance: %f\n", (double)slot->advance.x / 64 ));
    +    FT_TRACE5(( "  y advance: %f\n", (double)slot->advance.y / 64 ));
         FT_TRACE5(( "  linear x advance: %f\n",
    -                slot->linearHoriAdvance / 65536.0 ));
    +                (double)slot->linearHoriAdvance / 65536 ));
         FT_TRACE5(( "  linear y advance: %f\n",
    -                slot->linearVertAdvance / 65536.0 ));
    +                (double)slot->linearVertAdvance / 65536 ));
     
         {
           FT_Glyph_Metrics*  metrics = &slot->metrics;
     
     
           FT_TRACE5(( "  metrics:\n" ));
    -      FT_TRACE5(( "    width:  %f\n", metrics->width  / 64.0 ));
    -      FT_TRACE5(( "    height: %f\n", metrics->height / 64.0 ));
    +      FT_TRACE5(( "    width:  %f\n", (double)metrics->width / 64 ));
    +      FT_TRACE5(( "    height: %f\n", (double)metrics->height / 64 ));
           FT_TRACE5(( "\n" ));
    -      FT_TRACE5(( "    horiBearingX: %f\n", metrics->horiBearingX / 64.0 ));
    -      FT_TRACE5(( "    horiBearingY: %f\n", metrics->horiBearingY / 64.0 ));
    -      FT_TRACE5(( "    horiAdvance:  %f\n", metrics->horiAdvance  / 64.0 ));
    +      FT_TRACE5(( "    horiBearingX: %f\n",
    +                  (double)metrics->horiBearingX / 64 ));
    +      FT_TRACE5(( "    horiBearingY: %f\n",
    +                  (double)metrics->horiBearingY / 64 ));
    +      FT_TRACE5(( "    horiAdvance:  %f\n",
    +                  (double)metrics->horiAdvance / 64 ));
           FT_TRACE5(( "\n" ));
    -      FT_TRACE5(( "    vertBearingX: %f\n", metrics->vertBearingX / 64.0 ));
    -      FT_TRACE5(( "    vertBearingY: %f\n", metrics->vertBearingY / 64.0 ));
    -      FT_TRACE5(( "    vertAdvance:  %f\n", metrics->vertAdvance  / 64.0 ));
    +      FT_TRACE5(( "    vertBearingX: %f\n",
    +                  (double)metrics->vertBearingX / 64 ));
    +      FT_TRACE5(( "    vertBearingY: %f\n",
    +                  (double)metrics->vertBearingY / 64 ));
    +      FT_TRACE5(( "    vertAdvance:  %f\n",
    +                  (double)metrics->vertAdvance / 64 ));
         }
     #endif
     
    @@ -1488,7 +1495,7 @@
       static FT_Error
       open_face( FT_Driver      driver,
                  FT_Stream      *astream,
    -             FT_Bool        external_stream,
    +             FT_Bool        *anexternal_stream,
                  FT_Long        face_index,
                  FT_Int         num_params,
                  FT_Parameter*  params,
    @@ -1514,7 +1521,7 @@
         face->stream = *astream;
     
         /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
    -    if ( external_stream )
    +    if ( *anexternal_stream )
           face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
     
         if ( FT_NEW( internal ) )
    @@ -1544,7 +1551,10 @@
                                     (FT_Int)face_index,
                                     num_params,
                                     params );
    -    *astream = face->stream; /* Stream may have been changed. */
    +    /* Stream may have been changed. */
    +    *astream = face->stream;
    +    *anexternal_stream =
    +      ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0;
         if ( error )
           goto Fail;
     
    @@ -1668,13 +1678,13 @@
       static void
       memory_stream_close( FT_Stream  stream )
       {
    -    FT_Memory  memory = stream->memory;
    +    FT_Memory  memory = (FT_Memory)stream->descriptor.pointer;
     
     
         FT_FREE( stream->base );
    -
         stream->size  = 0;
         stream->close = NULL;
    +    FT_FREE( stream );
       }
     
     
    @@ -1705,7 +1715,8 @@
     
         FT_Stream_OpenMemory( stream, base, size );
     
    -    stream->close = close;
    +    stream->descriptor.pointer = memory;
    +    stream->close              = close;
     
         *astream = stream;
     
    @@ -1726,28 +1737,36 @@
       {
         FT_Open_Args  args;
         FT_Error      error;
    -    FT_Stream     stream = NULL;
         FT_Memory     memory = library->memory;
     
     
    +    args.flags = 0;
    +
    +    if ( driver_name )
    +    {
    +      args.driver = FT_Get_Module( library, driver_name );
    +      if ( !args.driver )
    +      {
    +        FT_FREE( base );
    +        return FT_THROW( Missing_Module );
    +      }
    +
    +      args.flags = args.flags | FT_OPEN_DRIVER;
    +    }
    +
    +    /* `memory_stream_close` also frees the stream object. */
         error = new_memory_stream( library,
                                    base,
                                    size,
                                    memory_stream_close,
    -                               &stream );
    +                               &args.stream );
         if ( error )
         {
           FT_FREE( base );
           return error;
         }
     
    -    args.flags  = FT_OPEN_STREAM;
    -    args.stream = stream;
    -    if ( driver_name )
    -    {
    -      args.flags  = args.flags | FT_OPEN_DRIVER;
    -      args.driver = FT_Get_Module( library, driver_name );
    -    }
    +    args.flags |= FT_OPEN_STREAM;
     
     #ifdef FT_MACINTOSH
         /* At this point, the face index has served its purpose;  */
    @@ -1759,21 +1778,7 @@
           face_index &= 0x7FFF0000L; /* retain GX data */
     #endif
     
    -    error = ft_open_face_internal( library, &args, face_index, aface, 0 );
    -
    -    if ( !error )
    -      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
    -    else
    -#ifdef FT_MACINTOSH
    -      FT_Stream_Free( stream, 0 );
    -#else
    -    {
    -      FT_Stream_Close( stream );
    -      FT_FREE( stream );
    -    }
    -#endif
    -
    -    return error;
    +    return ft_open_face_internal( library, &args, face_index, aface, 0 );
       }
     
     
    @@ -1916,7 +1921,7 @@
                                        sfnt_ps,
                                        length,
                                        FT_MIN( face_index, 0 ),
    -                                   is_sfnt_cid ? "cid" : "type1",
    +                                   is_sfnt_cid ? "t1cid" : "type1",
                                        aface );
       Exit:
         {
    @@ -2177,7 +2182,7 @@
         FT_Byte*   sfnt_data = NULL;
         FT_Error   error;
         FT_ULong   flag_offset;
    -    FT_Long    rlen;
    +    FT_ULong   rlen;
         int        is_cff;
         FT_Long    face_index_in_resource = 0;
     
    @@ -2192,11 +2197,11 @@
         if ( error )
           goto Exit;
     
    -    if ( FT_READ_LONG( rlen ) )
    +    if ( FT_READ_ULONG( rlen ) )
           goto Exit;
    -    if ( rlen < 1 )
    +    if ( !rlen )
           return FT_THROW( Cannot_Open_Resource );
    -    if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN )
    +    if ( rlen > FT_MAC_RFORK_MAX_LEN )
           return FT_THROW( Invalid_Offset );
     
         error = open_face_PS_from_sfnt_stream( library,
    @@ -2214,8 +2219,9 @@
     
         if ( FT_QALLOC( sfnt_data, rlen ) )
           return error;
    -    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, (FT_ULong)rlen );
    -    if ( error ) {
    +    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
    +    if ( error )
    +    {
           FT_FREE( sfnt_data );
           goto Exit;
         }
    @@ -2223,7 +2229,7 @@
         is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
         error = open_face_from_buffer( library,
                                        sfnt_data,
    -                                   (FT_ULong)rlen,
    +                                   rlen,
                                        face_index_in_resource,
                                        is_cff ? "cff" : "truetype",
                                        aface );
    @@ -2552,7 +2558,7 @@
     
         /* test for valid `library' delayed to `FT_Stream_New' */
     
    -    if ( ( !aface && face_index >= 0 ) || !args )
    +    if ( !args )
           return FT_THROW( Invalid_Argument );
     
         external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
    @@ -2563,6 +2569,14 @@
         if ( error )
           goto Fail3;
     
    +    /* Do this error check after `FT_Stream_New` to ensure that the */
    +    /* 'close' callback is called.                                  */
    +    if ( !aface && face_index >= 0 )
    +    {
    +      error = FT_THROW( Invalid_Argument );
    +      goto Fail3;
    +    }
    +
         memory = library->memory;
     
         /* If the font driver is specified in the `args' structure, use */
    @@ -2584,7 +2598,7 @@
               params     = args->params;
             }
     
    -        error = open_face( driver, &stream, external_stream, face_index,
    +        error = open_face( driver, &stream, &external_stream, face_index,
                                num_params, params, &face );
             if ( !error )
               goto Success;
    @@ -2620,7 +2634,7 @@
                 params     = args->params;
               }
     
    -          error = open_face( driver, &stream, external_stream, face_index,
    +          error = open_face( driver, &stream, &external_stream, face_index,
                                  num_params, params, &face );
               if ( !error )
                 goto Success;
    @@ -2852,8 +2866,8 @@
       /* documentation is in freetype.h */
     
       FT_EXPORT_DEF( FT_Error )
    -  FT_Attach_Stream( FT_Face        face,
    -                    FT_Open_Args*  parameters )
    +  FT_Attach_Stream( FT_Face              face,
    +                    const FT_Open_Args*  parameters )
       {
         FT_Stream  stream;
         FT_Error   error;
    @@ -3278,34 +3292,49 @@
           scaled_h = FT_REQUEST_HEIGHT( req );
     
           /* determine scales */
    -      if ( req->width )
    +      if ( req->height || !req->width )
           {
    -        metrics->x_scale = FT_DivFix( scaled_w, w );
    -
    -        if ( req->height )
    +        if ( h == 0 )
             {
    -          metrics->y_scale = FT_DivFix( scaled_h, h );
    -
    -          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
    -          {
    -            if ( metrics->y_scale > metrics->x_scale )
    -              metrics->y_scale = metrics->x_scale;
    -            else
    -              metrics->x_scale = metrics->y_scale;
    -          }
    +          FT_ERROR(( "FT_Request_Metrics: Divide by zero\n" ));
    +          error = FT_ERR( Divide_By_Zero );
    +          goto Exit;
             }
    -        else
    +
    +        metrics->y_scale = FT_DivFix( scaled_h, h );
    +      }
    +
    +      if ( req->width )
    +      {
    +        if ( w == 0 )
             {
    -          metrics->y_scale = metrics->x_scale;
    -          scaled_h = FT_MulDiv( scaled_w, h, w );
    +          FT_ERROR(( "FT_Request_Metrics: Divide by zero\n" ));
    +          error = FT_ERR( Divide_By_Zero );
    +          goto Exit;
             }
    +
    +        metrics->x_scale = FT_DivFix( scaled_w, w );
           }
           else
           {
    -        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
    +        metrics->x_scale = metrics->y_scale;
             scaled_w = FT_MulDiv( scaled_h, w, h );
           }
     
    +      if ( !req->height )
    +      {
    +        metrics->y_scale = metrics->x_scale;
    +        scaled_h = FT_MulDiv( scaled_w, h, w );
    +      }
    +
    +      if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
    +      {
    +        if ( metrics->y_scale > metrics->x_scale )
    +          metrics->y_scale = metrics->x_scale;
    +        else
    +          metrics->x_scale = metrics->y_scale;
    +      }
    +
       Calculate_Ppem:
           /* calculate the ppems */
           if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
    @@ -3379,15 +3408,19 @@
     
     
           FT_TRACE5(( "  x scale: %ld (%f)\n",
    -                  metrics->x_scale, metrics->x_scale / 65536.0 ));
    +                  metrics->x_scale, (double)metrics->x_scale / 65536 ));
           FT_TRACE5(( "  y scale: %ld (%f)\n",
    -                  metrics->y_scale, metrics->y_scale / 65536.0 ));
    -      FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
    -      FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
    -      FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
    -      FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
    -      FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
    -      FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
    +                  metrics->y_scale, (double)metrics->y_scale / 65536 ));
    +      FT_TRACE5(( "  ascender: %f\n",
    +                  (double)metrics->ascender / 64 ));
    +      FT_TRACE5(( "  descender: %f\n",
    +                  (double)metrics->descender / 64 ));
    +      FT_TRACE5(( "  height: %f\n",
    +                  (double)metrics->height / 64 ));
    +      FT_TRACE5(( "  max advance: %f\n",
    +                  (double)metrics->max_advance / 64 ));
    +      FT_TRACE5(( "  x ppem: %d\n", metrics->x_ppem ));
    +      FT_TRACE5(( "  y ppem: %d\n", metrics->y_ppem ));
         }
     #endif
     
    @@ -3459,15 +3492,19 @@
     
     
           FT_TRACE5(( "  x scale: %ld (%f)\n",
    -                  metrics->x_scale, metrics->x_scale / 65536.0 ));
    +                  metrics->x_scale, (double)metrics->x_scale / 65536 ));
           FT_TRACE5(( "  y scale: %ld (%f)\n",
    -                  metrics->y_scale, metrics->y_scale / 65536.0 ));
    -      FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
    -      FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
    -      FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
    -      FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
    -      FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
    -      FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
    +                  metrics->y_scale, (double)metrics->y_scale / 65536 ));
    +      FT_TRACE5(( "  ascender: %f\n",
    +                  (double)metrics->ascender / 64 ));
    +      FT_TRACE5(( "  descender: %f\n",
    +                  (double)metrics->descender / 64 ));
    +      FT_TRACE5(( "  height: %f\n",
    +                  (double)metrics->height / 64 ));
    +      FT_TRACE5(( "  max advance: %f\n",
    +                  (double)metrics->max_advance / 64 ));
    +      FT_TRACE5(( "  x ppem: %d\n", metrics->x_ppem ));
    +      FT_TRACE5(( "  y ppem: %d\n", metrics->y_ppem ));
         }
     #endif
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType outline management (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -130,7 +130,7 @@
           }
     
           FT_TRACE5(( "  move to (%.2f, %.2f)\n",
    -                  v_start.x / 64.0, v_start.y / 64.0 ));
    +                  (double)v_start.x / 64, (double)v_start.y / 64 ));
           error = func_interface->move_to( &v_start, user );
           if ( error )
             goto Exit;
    @@ -152,7 +152,7 @@
                 vec.y = SCALED( point->y );
     
                 FT_TRACE5(( "  line to (%.2f, %.2f)\n",
    -                        vec.x / 64.0, vec.y / 64.0 ));
    +                        (double)vec.x / 64, (double)vec.y / 64 ));
                 error = func_interface->line_to( &vec, user );
                 if ( error )
                   goto Exit;
    @@ -181,8 +181,10 @@
                 {
                   FT_TRACE5(( "  conic to (%.2f, %.2f)"
                               " with control (%.2f, %.2f)\n",
    -                          vec.x / 64.0, vec.y / 64.0,
    -                          v_control.x / 64.0, v_control.y / 64.0 ));
    +                          (double)vec.x / 64,
    +                          (double)vec.y / 64,
    +                          (double)v_control.x / 64,
    +                          (double)v_control.y / 64 ));
                   error = func_interface->conic_to( &v_control, &vec, user );
                   if ( error )
                     goto Exit;
    @@ -197,8 +199,10 @@
     
                 FT_TRACE5(( "  conic to (%.2f, %.2f)"
                             " with control (%.2f, %.2f)\n",
    -                        v_middle.x / 64.0, v_middle.y / 64.0,
    -                        v_control.x / 64.0, v_control.y / 64.0 ));
    +                        (double)v_middle.x / 64,
    +                        (double)v_middle.y / 64,
    +                        (double)v_control.x / 64,
    +                        (double)v_control.y / 64 ));
                 error = func_interface->conic_to( &v_control, &v_middle, user );
                 if ( error )
                   goto Exit;
    @@ -209,8 +213,10 @@
     
               FT_TRACE5(( "  conic to (%.2f, %.2f)"
                           " with control (%.2f, %.2f)\n",
    -                      v_start.x / 64.0, v_start.y / 64.0,
    -                      v_control.x / 64.0, v_control.y / 64.0 ));
    +                      (double)v_start.x / 64,
    +                      (double)v_start.y / 64,
    +                      (double)v_control.x / 64,
    +                      (double)v_control.y / 64 ));
               error = func_interface->conic_to( &v_control, &v_start, user );
               goto Close;
     
    @@ -242,9 +248,12 @@
     
                   FT_TRACE5(( "  cubic to (%.2f, %.2f)"
                               " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
    -                          vec.x / 64.0, vec.y / 64.0,
    -                          vec1.x / 64.0, vec1.y / 64.0,
    -                          vec2.x / 64.0, vec2.y / 64.0 ));
    +                          (double)vec.x / 64,
    +                          (double)vec.y / 64,
    +                          (double)vec1.x / 64,
    +                          (double)vec1.y / 64,
    +                          (double)vec2.x / 64,
    +                          (double)vec2.y / 64 ));
                   error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
                   if ( error )
                     goto Exit;
    @@ -253,9 +262,12 @@
     
                 FT_TRACE5(( "  cubic to (%.2f, %.2f)"
                             " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
    -                        v_start.x / 64.0, v_start.y / 64.0,
    -                        vec1.x / 64.0, vec1.y / 64.0,
    -                        vec2.x / 64.0, vec2.y / 64.0 ));
    +                        (double)v_start.x / 64,
    +                        (double)v_start.y / 64,
    +                        (double)vec1.x / 64,
    +                        (double)vec1.y / 64,
    +                        (double)vec2.x / 64,
    +                        (double)vec2.y / 64 ));
                 error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
                 goto Close;
               }
    @@ -264,7 +276,7 @@
     
           /* close the contour with a line segment */
           FT_TRACE5(( "  line to (%.2f, %.2f)\n",
    -                  v_start.x / 64.0, v_start.y / 64.0 ));
    +                  (double)v_start.x / 64, (double)v_start.y / 64 ));
           error = func_interface->line_to( &v_start, user );
     
         Close:
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftpatent.c	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   FreeType API for checking patented TrueType bytecode instructions
      *   (body).  Obsolete, retained for backward compatibility.
      *
    - * Copyright (C) 2007-2022 by
    + * Copyright (C) 2007-2023 by
      * David Turner.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftpsprop.c	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Get and set properties of PostScript drivers (body).
      *   See `ftdriver.h' for available properties.
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftrfork.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Embedded resource forks accessor (body).
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * Masatake YAMATO and Redhat K.K.
      *
      * FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftsnames.c	2023-10-06 05:33:33.000000000 +0000
    @@ -7,7 +7,7 @@
      *
      *   This is _not_ used to retrieve glyph names!
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftstream.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftstream.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftstream.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftstream.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   I/O stream support (body).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -261,7 +261,7 @@
           }
     
     #ifdef FT_DEBUG_MEMORY
    -      /* assume _ft_debug_file and _ft_debug_lineno are already set */
    +      /* assume `ft_debug_file_` and `ft_debug_lineno_` are already set */
           stream->base = (unsigned char*)ft_mem_qalloc( memory,
                                                         (FT_Long)count,
                                                         &error );
    @@ -363,11 +363,11 @@
       }
     
     
    -  FT_BASE_DEF( FT_UShort )
    +  FT_BASE_DEF( FT_UInt16 )
       FT_Stream_GetUShort( FT_Stream  stream )
       {
         FT_Byte*   p;
    -    FT_UShort  result;
    +    FT_UInt16  result;
     
     
         FT_ASSERT( stream && stream->cursor );
    @@ -382,11 +382,11 @@
       }
     
     
    -  FT_BASE_DEF( FT_UShort )
    +  FT_BASE_DEF( FT_UInt16 )
       FT_Stream_GetUShortLE( FT_Stream  stream )
       {
         FT_Byte*   p;
    -    FT_UShort  result;
    +    FT_UInt16  result;
     
     
         FT_ASSERT( stream && stream->cursor );
    @@ -401,11 +401,11 @@
       }
     
     
    -  FT_BASE_DEF( FT_ULong )
    +  FT_BASE_DEF( FT_UInt32 )
       FT_Stream_GetUOffset( FT_Stream  stream )
       {
         FT_Byte*  p;
    -    FT_ULong  result;
    +    FT_UInt32 result;
     
     
         FT_ASSERT( stream && stream->cursor );
    @@ -419,11 +419,11 @@
       }
     
     
    -  FT_BASE_DEF( FT_ULong )
    +  FT_BASE_DEF( FT_UInt32 )
       FT_Stream_GetULong( FT_Stream  stream )
       {
         FT_Byte*  p;
    -    FT_ULong  result;
    +    FT_UInt32 result;
     
     
         FT_ASSERT( stream && stream->cursor );
    @@ -437,11 +437,11 @@
       }
     
     
    -  FT_BASE_DEF( FT_ULong )
    +  FT_BASE_DEF( FT_UInt32 )
       FT_Stream_GetULongLE( FT_Stream  stream )
       {
         FT_Byte*  p;
    -    FT_ULong  result;
    +    FT_UInt32 result;
     
     
         FT_ASSERT( stream && stream->cursor );
    @@ -493,13 +493,13 @@
       }
     
     
    -  FT_BASE_DEF( FT_UShort )
    +  FT_BASE_DEF( FT_UInt16 )
       FT_Stream_ReadUShort( FT_Stream  stream,
                             FT_Error*  error )
       {
         FT_Byte    reads[2];
         FT_Byte*   p;
    -    FT_UShort  result = 0;
    +    FT_UInt16  result = 0;
     
     
         FT_ASSERT( stream );
    @@ -538,13 +538,13 @@
       }
     
     
    -  FT_BASE_DEF( FT_UShort )
    +  FT_BASE_DEF( FT_UInt16 )
       FT_Stream_ReadUShortLE( FT_Stream  stream,
                               FT_Error*  error )
       {
         FT_Byte    reads[2];
         FT_Byte*   p;
    -    FT_UShort  result = 0;
    +    FT_UInt16  result = 0;
     
     
         FT_ASSERT( stream );
    @@ -628,13 +628,13 @@
       }
     
     
    -  FT_BASE_DEF( FT_ULong )
    +  FT_BASE_DEF( FT_UInt32 )
       FT_Stream_ReadULong( FT_Stream  stream,
                            FT_Error*  error )
       {
         FT_Byte   reads[4];
         FT_Byte*  p;
    -    FT_ULong  result = 0;
    +    FT_UInt32 result = 0;
     
     
         FT_ASSERT( stream );
    @@ -673,13 +673,13 @@
       }
     
     
    -  FT_BASE_DEF( FT_ULong )
    +  FT_BASE_DEF( FT_UInt32 )
       FT_Stream_ReadULongLE( FT_Stream  stream,
                              FT_Error*  error )
       {
         FT_Byte   reads[4];
         FT_Byte*  p;
    -    FT_ULong  result = 0;
    +    FT_UInt32 result = 0;
     
     
         FT_ASSERT( stream );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType path stroker (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType synthesizing code for emboldening and slanting (body).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -46,6 +46,18 @@
       FT_EXPORT_DEF( void )
       FT_GlyphSlot_Oblique( FT_GlyphSlot  slot )
       {
    +    /* Value '0x0366A' corresponds to a shear angle of about 12 degrees. */
    +    FT_GlyphSlot_Slant( slot, 0x0366A, 0 );
    +  }
    +
    +
    +  /* documentation is in ftsynth.h */
    +
    +  FT_EXPORT_DEF( void )
    +  FT_GlyphSlot_Slant( FT_GlyphSlot  slot,
    +                      FT_Fixed      xslant,
    +                      FT_Fixed      yslant )
    +  {
         FT_Matrix    transform;
         FT_Outline*  outline;
     
    @@ -61,13 +73,11 @@
     
         /* we don't touch the advance width */
     
    -    /* For italic, simply apply a shear transform, with an angle */
    -    /* of about 12 degrees.                                      */
    -
    +    /* For italic, simply apply a shear transform */
         transform.xx = 0x10000L;
    -    transform.yx = 0x00000L;
    +    transform.yx = -yslant;
     
    -    transform.xy = 0x0366AL;
    +    transform.xy = xslant;
         transform.yy = 0x10000L;
     
         FT_Outline_Transform( outline, &transform );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   ANSI-specific FreeType low-level system interface (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/fttrigon.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType trigonometric functions (body).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/fttype1.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/fttype1.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/fttype1.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/fttype1.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType utility file for PS names support (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftutil.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftutil.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/base/ftutil.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/base/ftutil.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType utility file for memory and list management (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CFF character mapping table (cmap) support (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CFF character mapping table (cmap) support (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,8 +4,8 @@
      *
      *   OpenType font driver implementation (body).
      *
    - * Copyright (C) 1996-2022 by
    - * David Turner, Robert Wilhelm, and Werner Lemberg.
    + * Copyright (C) 1996-2023 by
    + * David Turner, Robert Wilhelm, Werner Lemberg, and Dominik Röttsches.
      *
      * This file is part of the FreeType project, and may only be used,
      * modified, and distributed under the terms of the FreeType project
    @@ -936,22 +936,103 @@
       }
     
     
    +  static FT_Error
    +  cff_load_item_variation_store( CFF_Face         face,
    +                                 FT_ULong         offset,
    +                                 GX_ItemVarStore  itemStore )
    +  {
    +    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +    return mm->load_item_var_store( FT_FACE(face), offset, itemStore );
    +  }
    +
    +
    +  static FT_Error
    +  cff_load_delta_set_index_mapping( CFF_Face           face,
    +                                    FT_ULong           offset,
    +                                    GX_DeltaSetIdxMap  map,
    +                                    GX_ItemVarStore    itemStore,
    +                                    FT_ULong           table_len )
    +  {
    +    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +    return mm->load_delta_set_idx_map( FT_FACE( face ), offset, map,
    +                                       itemStore, table_len );
    +  }
    +
    +
    +  static FT_Int
    +  cff_get_item_delta( CFF_Face         face,
    +                      GX_ItemVarStore  itemStore,
    +                      FT_UInt          outerIndex,
    +                      FT_UInt          innerIndex )
    +  {
    +    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +    return mm->get_item_delta( FT_FACE( face ), itemStore,
    +                               outerIndex, innerIndex );
    +  }
    +
    +
    +  static void
    +  cff_done_item_variation_store( CFF_Face          face,
    +                                 GX_ItemVarStore  itemStore )
    +  {
    +    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +    mm->done_item_var_store( FT_FACE( face ), itemStore );
    +  }
    +
    +
    +  static void
    +  cff_done_delta_set_index_map( CFF_Face           face,
    +                                GX_DeltaSetIdxMap  deltaSetIdxMap )
    +  {
    +    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +    mm->done_delta_set_idx_map( FT_FACE ( face ), deltaSetIdxMap );
    +  }
    +
    +
    +
       FT_DEFINE_SERVICE_MULTIMASTERSREC(
         cff_service_multi_masters,
     
    -    (FT_Get_MM_Func)             NULL,                    /* get_mm              */
    -    (FT_Set_MM_Design_Func)      NULL,                    /* set_mm_design       */
    -    (FT_Set_MM_Blend_Func)       cff_set_mm_blend,        /* set_mm_blend        */
    -    (FT_Get_MM_Blend_Func)       cff_get_mm_blend,        /* get_mm_blend        */
    -    (FT_Get_MM_Var_Func)         cff_get_mm_var,          /* get_mm_var          */
    -    (FT_Set_Var_Design_Func)     cff_set_var_design,      /* set_var_design      */
    -    (FT_Get_Var_Design_Func)     cff_get_var_design,      /* get_var_design      */
    -    (FT_Set_Instance_Func)       cff_set_instance,        /* set_instance        */
    -    (FT_Set_MM_WeightVector_Func)cff_set_mm_weightvector, /* set_mm_weightvector */
    -    (FT_Get_MM_WeightVector_Func)cff_get_mm_weightvector, /* get_mm_weightvector */
    -
    -    (FT_Get_Var_Blend_Func)      cff_get_var_blend,       /* get_var_blend       */
    -    (FT_Done_Blend_Func)         cff_done_blend           /* done_blend          */
    +    (FT_Get_MM_Func)        NULL,               /* get_mm                    */
    +    (FT_Set_MM_Design_Func) NULL,               /* set_mm_design             */
    +    (FT_Set_MM_Blend_Func)  cff_set_mm_blend,   /* set_mm_blend              */
    +    (FT_Get_MM_Blend_Func)  cff_get_mm_blend,   /* get_mm_blend              */
    +    (FT_Get_MM_Var_Func)    cff_get_mm_var,     /* get_mm_var                */
    +    (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design            */
    +    (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design            */
    +    (FT_Set_Instance_Func)  cff_set_instance,   /* set_instance              */
    +    (FT_Set_MM_WeightVector_Func)
    +                            cff_set_mm_weightvector,
    +                                                /* set_mm_weightvector       */
    +    (FT_Get_MM_WeightVector_Func)
    +                            cff_get_mm_weightvector,
    +                                                /* get_mm_weightvector       */
    +    (FT_Var_Load_Delta_Set_Idx_Map_Func)
    +                            cff_load_delta_set_index_mapping,
    +                                                /* load_delta_set_idx_map    */
    +    (FT_Var_Load_Item_Var_Store_Func)
    +                            cff_load_item_variation_store,
    +                                                /* load_item_variation_store */
    +    (FT_Var_Get_Item_Delta_Func)
    +                            cff_get_item_delta, /* get_item_delta            */
    +    (FT_Var_Done_Item_Var_Store_Func)
    +                            cff_done_item_variation_store,
    +                                                /* done_item_variation_store */
    +    (FT_Var_Done_Delta_Set_Idx_Map_Func)
    +                            cff_done_delta_set_index_map,
    +                                                /* done_delta_set_index_map  */
    +    (FT_Get_Var_Blend_Func) cff_get_var_blend,  /* get_var_blend             */
    +    (FT_Done_Blend_Func)    cff_done_blend      /* done_blend                */
       )
     
     
    @@ -1027,8 +1108,7 @@
       /*************************************************************************/
       /*************************************************************************/
     
    -#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \
    -     defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +#if defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
       FT_DEFINE_SERVICEDESCREC10(
         cff_services,
     
    @@ -1043,7 +1123,7 @@
         FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
         FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
       )
    -#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES
    +#else
       FT_DEFINE_SERVICEDESCREC8(
         cff_services,
     
    @@ -1054,32 +1134,6 @@
         FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
         FT_SERVICE_ID_CID,                  &cff_service_cid_info,
         FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
    -    FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
    -  )
    -#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT
    -  FT_DEFINE_SERVICEDESCREC9(
    -    cff_services,
    -
    -    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
    -    FT_SERVICE_ID_MULTI_MASTERS,        &cff_service_multi_masters,
    -    FT_SERVICE_ID_METRICS_VARIATIONS,   &cff_service_metrics_var,
    -    FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info,
    -    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name,
    -    FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
    -    FT_SERVICE_ID_CID,                  &cff_service_cid_info,
    -    FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
    -    FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
    -  )
    -#else
    -  FT_DEFINE_SERVICEDESCREC7(
    -    cff_services,
    -
    -    FT_SERVICE_ID_FONT_FORMAT,          FT_FONT_FORMAT_CFF,
    -    FT_SERVICE_ID_POSTSCRIPT_INFO,      &cff_service_ps_info,
    -    FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cff_service_ps_name,
    -    FT_SERVICE_ID_TT_CMAP,              &cff_service_get_cmap_info,
    -    FT_SERVICE_ID_CID,                  &cff_service_cid_info,
    -    FT_SERVICE_ID_PROPERTIES,           &cff_service_properties,
         FT_SERVICE_ID_CFF_LOAD,             &cff_service_cff_load
       )
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level OpenType driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cfferrs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CFF error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType Glyph Loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -356,18 +356,14 @@
     
     #ifdef FT_CONFIG_OPTION_SVG
         /* check for OT-SVG */
    -    if ( ( load_flags & FT_LOAD_COLOR )     &&
    -         ( (TT_Face)glyph->root.face )->svg )
    +    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
         {
           /*
            * We load the SVG document and try to grab the advances from the
            * table.  For the bearings we rely on the presetting hook to do that.
            */
     
    -      FT_Short      dummy;
    -      FT_UShort     advanceX;
    -      FT_UShort     advanceY;
    -      SFNT_Service  sfnt;
    +      SFNT_Service  sfnt  = (SFNT_Service)face->sfnt;
     
     
           if ( size && (size->root.metrics.x_ppem < 1 ||
    @@ -379,10 +375,17 @@
     
           FT_TRACE3(( "Trying to load SVG glyph\n" ));
     
    -      sfnt  = (SFNT_Service)((TT_Face)glyph->root.face)->sfnt;
           error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
           if ( !error )
           {
    +        FT_Fixed  x_scale = size->root.metrics.x_scale;
    +        FT_Fixed  y_scale = size->root.metrics.y_scale;
    +
    +        FT_Short   dummy;
    +        FT_UShort  advanceX;
    +        FT_UShort  advanceY;
    +
    +
             FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
     
             glyph->root.format = FT_GLYPH_FORMAT_SVG;
    @@ -404,17 +407,11 @@
                                &dummy,
                                &advanceY );
     
    -        advanceX =
    -          (FT_UShort)FT_MulDiv( advanceX,
    -                                glyph->root.face->size->metrics.x_ppem,
    -                                glyph->root.face->units_per_EM );
    -        advanceY =
    -          (FT_UShort)FT_MulDiv( advanceY,
    -                                glyph->root.face->size->metrics.y_ppem,
    -                                glyph->root.face->units_per_EM );
    +        glyph->root.linearHoriAdvance = advanceX;
    +        glyph->root.linearVertAdvance = advanceY;
     
    -        glyph->root.metrics.horiAdvance = advanceX << 6;
    -        glyph->root.metrics.vertAdvance = advanceY << 6;
    +        glyph->root.metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
    +        glyph->root.metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
     
             return error;
           }
    @@ -491,13 +488,14 @@
           decoder.builder.no_recurse =
             FT_BOOL( load_flags & FT_LOAD_NO_RECURSE );
     
    -      /* now load the unscaled outline */
    -      error = cff_get_glyph_data( face, glyph_index,
    -                                  &charstring, &charstring_len );
    +      /* this function also checks for a valid subfont index */
    +      error = decoder_funcs->prepare( &decoder, size, glyph_index );
           if ( error )
             goto Glyph_Build_Finished;
     
    -      error = decoder_funcs->prepare( &decoder, size, glyph_index );
    +      /* now load the unscaled outline */
    +      error = cff_get_glyph_data( face, glyph_index,
    +                                  &charstring, &charstring_len );
           if ( error )
             goto Glyph_Build_Finished;
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffgload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType Glyph Loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType and CFF data/program tables loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1288,7 +1288,7 @@
       /* Blended values are written to a different buffer,     */
       /* using reserved operator 255.                          */
       /*                                                       */
    -  /* Blend calculation is done in 16.16 fixed point.       */
    +  /* Blend calculation is done in 16.16 fixed-point.       */
       FT_LOCAL_DEF( FT_Error )
       cff_blend_doBlend( CFF_SubFont  subFont,
                          CFF_Parser   parser,
    @@ -1364,7 +1364,7 @@
           FT_UInt32        sum;
     
     
    -      /* convert inputs to 16.16 fixed point */
    +      /* convert inputs to 16.16 fixed-point */
           sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
     
           for ( j = 1; j < blend->lenBV; j++ )
    @@ -1373,7 +1373,7 @@
           /* point parser stack to new value on blend_stack */
           parser->stack[i + base] = subFont->blend_top;
     
    -      /* Push blended result as Type 2 5-byte fixed point number.  This */
    +      /* Push blended result as Type 2 5-byte fixed-point number.  This */
           /* will not conflict with actual DICTs because 255 is a reserved  */
           /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
           /* decode of this, which rounds to an integer.                    */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType & CFF data/program tables loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType objects manager (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1031,12 +1031,10 @@
             cffface->style_flags = flags;
           }
     
    -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
           /* CID-keyed CFF or CFF2 fonts don't have glyph names -- the SFNT */
           /* loader has unset this flag because of the 3.0 `post' table.    */
           if ( dict->cid_registry == 0xFFFFU && !cff2 )
             cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
    -#endif
     
           if ( dict->cid_registry != 0xFFFFU && pure_cff )
             cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType objects manager (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CFF token stream parser (body)
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -530,7 +530,7 @@
     
         else if ( **d == 255 )
         {
    -      /* 16.16 fixed point is used internally for CFF2 blend results. */
    +      /* 16.16 fixed-point is used internally for CFF2 blend results. */
           /* Since these are trusted values, a limit check is not needed. */
     
           /* After the 255, 4 bytes give the number.                 */
    @@ -758,12 +758,12 @@
           *upm = (FT_ULong)power_tens[-max_scaling];
     
           FT_TRACE4(( " [%f %f %f %f %f %f]\n",
    -                  (double)matrix->xx / *upm / 65536,
    -                  (double)matrix->xy / *upm / 65536,
    -                  (double)matrix->yx / *upm / 65536,
    -                  (double)matrix->yy / *upm / 65536,
    -                  (double)offset->x  / *upm / 65536,
    -                  (double)offset->y  / *upm / 65536 ));
    +                  (double)matrix->xx / (double)*upm / 65536,
    +                  (double)matrix->xy / (double)*upm / 65536,
    +                  (double)matrix->yx / (double)*upm / 65536,
    +                  (double)matrix->yy / (double)*upm / 65536,
    +                  (double)offset->x  / (double)*upm / 65536,
    +                  (double)offset->y  / (double)*upm / 65536 ));
     
           if ( !FT_Matrix_Check( matrix ) )
           {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CFF token stream parser (specification)
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cff/cfftoken.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CFF token definitions (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/ciderrs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID-keyed Type1 Glyph Loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   OpenType Glyph Loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID-keyed Type1 font loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID-keyed Type1 font loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID objects manager (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -153,7 +153,7 @@
       }
     
     
    -  FT_LOCAL( FT_Error )
    +  FT_LOCAL_DEF( FT_Error )
       cid_size_request( FT_Size          size,
                         FT_Size_Request  req )
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID objects manager (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID-keyed Type1 parser (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidparse.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID-keyed Type1 parser (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID driver interface (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidriver.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level CID driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/cid/cidtoken.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   CID token definitions (specification only).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   AFM parser (body).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -563,7 +563,7 @@
       }
     
     
    -  FT_LOCAL( void )
    +  FT_LOCAL_DEF( void )
       afm_parser_done( AFM_Parser  parser )
       {
         FT_Memory  memory = parser->memory;
    @@ -1061,7 +1061,7 @@
             if ( error )
               goto Fail;
             /* we only support kern data, so ... */
    -        /* fall through                      */
    +        FALL_THROUGH;
     
           case AFM_TOKEN_ENDFONTMETRICS:
             return FT_Err_Ok;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   AFM parser (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript CFF (Type 2) decoding routines (body).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript CFF (Type 2) decoding routines (specification).
      *
    - * Copyright (C) 2017-2022 by
    + * Copyright (C) 2017-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psauxerr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PS auxiliary module error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType auxiliary PostScript module implementation (body).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psauxmod.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType auxiliary PostScript module implementation (specification).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psconv.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Some convenience conversions (body).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psconv.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Some convenience conversions (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psfixed.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psfixed.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psfixed.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psfixed.h	2023-10-06 05:33:33.000000000 +0000
    @@ -2,7 +2,7 @@
      *
      * psfixed.h
      *
    - *   Adobe's code for Fixed Point Mathematics (specification only).
    + *   Adobe's code for Fixed-Point Mathematics (specification only).
      *
      * Copyright 2007-2013 Adobe Systems Incorporated.
      *
    @@ -43,10 +43,10 @@
     FT_BEGIN_HEADER
     
     
    -  /* rasterizer integer and fixed point arithmetic must be 32-bit */
    +  /* rasterizer integer and fixed-point arithmetic must be 32-bit */
     
     #define   CF2_Fixed  CF2_F16Dot16
    -  typedef FT_Int32   CF2_Frac;   /* 2.30 fixed point */
    +  typedef FT_Int32   CF2_Frac;   /* 2.30 fixed-point */
     
     
     #define CF2_FIXED_MAX      ( (CF2_Fixed)0x7FFFFFFFL )
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psft.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psft.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psft.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psft.c	2023-10-06 05:33:33.000000000 +0000
    @@ -68,11 +68,10 @@
         CF2_Fixed  maxScale;
     
     
    -    FT_ASSERT( unitsPerEm > 0 );
    -
         if ( transform->a <= 0 || transform->d <= 0 )
           return FT_THROW( Invalid_Size_Handle );
     
    +    FT_ASSERT( unitsPerEm > 0 );
         FT_ASSERT( transform->b == 0 && transform->c == 0 );
         FT_ASSERT( transform->tx == 0 && transform->ty == 0 );
     
    @@ -297,7 +296,6 @@
       cf2_getUnitsPerEm( PS_Decoder*  decoder )
       {
         FT_ASSERT( decoder && decoder->builder.face );
    -    FT_ASSERT( decoder->builder.face->units_per_EM );
     
         return decoder->builder.face->units_per_EM;
       }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psglue.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psglue.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psglue.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psglue.h	2023-10-06 05:33:33.000000000 +0000
    @@ -72,7 +72,7 @@
       } CF2_PathOp;
     
     
    -  /* a matrix of fixed point values */
    +  /* a matrix of fixed-point values */
       typedef struct  CF2_Matrix_
       {
         CF2_F16Dot16  a;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c	2023-10-06 05:33:33.000000000 +0000
    @@ -693,8 +693,10 @@
             CF2_Fixed  midpoint =
                          cf2_hintmap_map(
                            hintmap->initialHintMap,
    -                       ADD_INT32( secondHintEdge->csCoord,
    -                                  firstHintEdge->csCoord ) / 2 );
    +                       ADD_INT32(
    +                         firstHintEdge->csCoord,
    +                         SUB_INT32 ( secondHintEdge->csCoord,
    +                                     firstHintEdge->csCoord ) / 2 ) );
             CF2_Fixed  halfWidth =
                          FT_MulFix( SUB_INT32( secondHintEdge->csCoord,
                                                firstHintEdge->csCoord ) / 2,
    @@ -1034,10 +1036,10 @@
         {
           FT_TRACE6(( "flags: [p]air [g]host [t]op"
                       " [b]ottom [L]ocked [S]ynthetic\n" ));
    -      FT_TRACE6(( "Initial hintmap" ));
    +      FT_TRACE6(( "Initial hintmap:\n" ));
         }
         else
    -      FT_TRACE6(( "Hints:" ));
    +      FT_TRACE6(( "Hints:\n" ));
     #endif
     
         cf2_hintmap_dump( hintmap );
    @@ -1054,7 +1056,7 @@
         /* adjust positions of hint edges that are not locked to blue zones */
         cf2_hintmap_adjustHints( hintmap );
     
    -    FT_TRACE6(( "(adjusted)\n" ));
    +    FT_TRACE6(( "Hints adjusted:\n" ));
         cf2_hintmap_dump( hintmap );
     
         /* save the position of all hints that were used in this hint map; */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auxiliary functions for PostScript fonts (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -84,7 +84,6 @@
     
         table->max_elems = count;
         table->init      = 0xDEADBEEFUL;
    -    table->num_elems = 0;
         table->block     = NULL;
         table->capacity  = 0;
         table->cursor    = 0;
    @@ -235,7 +234,7 @@
         FT_Memory  memory = table->memory;
     
     
    -    if ( (FT_ULong)table->init == 0xDEADBEEFUL )
    +    if ( table->init == 0xDEADBEEFUL )
         {
           FT_FREE( table->block );
           FT_FREE( table->elements );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psobjs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Auxiliary functions for PostScript fonts (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psstack.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psstack.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/psstack.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/psstack.h	2023-10-06 05:33:33.000000000 +0000
    @@ -49,8 +49,8 @@
       {
         union
         {
    -      CF2_Fixed  r;      /* 16.16 fixed point */
    -      CF2_Frac   f;      /* 2.30 fixed point (for font matrix) */
    +      CF2_Fixed  r;      /* 16.16 fixed-point */
    +      CF2_Frac   f;      /* 2.30 fixed-point (for font matrix) */
           CF2_Int    i;
         } u;
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 character map support (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 character map support (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript Type 1 decoding routines (body).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript Type 1 decoding routines (specification).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript hinting algorithm (body).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript hinting algorithm (specification).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.c	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   PostScript hinter global hinting management (body).
      *   Inspired by the new auto-hinter module.
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshglob.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript hinter global hinting management.
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType PostScript hinter module implementation (body).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript hinter module interface (specification).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshnterr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PS Hinter error codes (specification only).
      *
    - * Copyright (C) 2003-2022 by
    + * Copyright (C) 2003-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType PostScript hints recorder (body).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -765,7 +765,7 @@
     
     
       /* destroy hints */
    -  FT_LOCAL( void )
    +  FT_LOCAL_DEF( void )
       ps_hints_done( PS_Hints  hints )
       {
         FT_Memory  memory = hints->memory;
    @@ -779,7 +779,7 @@
       }
     
     
    -  FT_LOCAL( void )
    +  FT_LOCAL_DEF( void )
       ps_hints_init( PS_Hints   hints,
                      FT_Memory  memory )
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Postscript (Type1/Type2) hints recorder (specification).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   psnames module implementation (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -412,21 +412,18 @@
       ps_unicodes_char_index( PS_Unicodes  table,
                               FT_UInt32    unicode )
       {
    -    PS_UniMap  *min, *max, *mid, *result = NULL;
    +    PS_UniMap  *result = NULL;
    +    PS_UniMap  *min = table->maps;
    +    PS_UniMap  *max = min + table->num_maps;
    +    PS_UniMap  *mid = min + ( ( max - min ) >> 1 );
     
     
         /* Perform a binary search on the table. */
    -
    -    min = table->maps;
    -    max = min + table->num_maps - 1;
    -
    -    while ( min <= max )
    +    while ( min < max )
         {
           FT_UInt32  base_glyph;
     
     
    -      mid = min + ( ( max - min ) >> 1 );
    -
           if ( mid->unicode == unicode )
           {
             result = mid;
    @@ -438,13 +435,15 @@
           if ( base_glyph == unicode )
             result = mid; /* remember match but continue search for base glyph */
     
    -      if ( min == max )
    -        break;
    -
           if ( base_glyph < unicode )
             min = mid + 1;
           else
    -        max = mid - 1;
    +        max = mid;
    +
    +      /* reasonable prediction in a continuous block */
    +      mid += unicode - base_glyph;
    +      if ( mid >= max || mid < min )
    +        mid = min + ( ( max - min ) >> 1 );
         }
     
         if ( result )
    @@ -465,14 +464,13 @@
         {
           FT_UInt     min = 0;
           FT_UInt     max = table->num_maps;
    -      FT_UInt     mid;
    +      FT_UInt     mid = min + ( ( max - min ) >> 1 );
           PS_UniMap*  map;
           FT_UInt32   base_glyph;
     
     
           while ( min < max )
           {
    -        mid = min + ( ( max - min ) >> 1 );
             map = table->maps + mid;
     
             if ( map->unicode == char_code )
    @@ -490,6 +488,11 @@
               min = mid + 1;
             else
               max = mid;
    +
    +        /* reasonable prediction in a continuous block */
    +        mid += char_code - base_glyph;
    +        if ( mid >= max || mid < min )
    +          mid = min + ( max - min ) / 2;
           }
     
           if ( result )
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level psnames module interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/psnamerr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PS names module error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/psnames/pstables.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PostScript glyph names.
      *
    - * Copyright (C) 2005-2022 by
    + * Copyright (C) 2005-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftmisc.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   Miscellaneous macros for stand-alone rasterizer (specification
      *   only).
      *
    - * Copyright (C) 2005-2022 by
    + * Copyright (C) 2005-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph rasterizer (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -2219,8 +2219,8 @@
         /* represent multiples of 1/(1<<12) = 1/4096                    */
         FT_TRACE7(( "  y=%d x=[% .12f;% .12f]",
                     y,
    -                x1 / (double)ras.precision,
    -                x2 / (double)ras.precision ));
    +                (double)x1 / (double)ras.precision,
    +                (double)x2 / (double)ras.precision ));
     
         /* Drop-out control */
     
    @@ -2294,8 +2294,8 @@
     
         FT_TRACE7(( "  y=%d x=[% .12f;% .12f]",
                     y,
    -                x1 / (double)ras.precision,
    -                x2 / (double)ras.precision ));
    +                (double)x1 / (double)ras.precision,
    +                (double)x2 / (double)ras.precision ));
     
         /* Drop-out control */
     
    @@ -2477,8 +2477,8 @@
     
         FT_TRACE7(( "  x=%d y=[% .12f;% .12f]",
                     y,
    -                x1 / (double)ras.precision,
    -                x2 / (double)ras.precision ));
    +                (double)x1 / (double)ras.precision,
    +                (double)x2 / (double)ras.precision ));
     
         /* We should not need this procedure but the vertical sweep   */
         /* mishandles horizontal lines through pixel centers.  So we  */
    @@ -2548,8 +2548,8 @@
     
         FT_TRACE7(( "  x=%d y=[% .12f;% .12f]",
                     y,
    -                x1 / (double)ras.precision,
    -                x2 / (double)ras.precision ));
    +                (double)x1 / (double)ras.precision,
    +                (double)x2 / (double)ras.precision ));
     
         /* During the horizontal sweep, we only take care of drop-outs */
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftraster.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph rasterizer (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph rasterizer interface (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   The FreeType glyph rasterizer interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/raster/rasterrs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   monochrome renderer error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PNG Bitmap glyph support.
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * Google, Inc.
      * Written by Stuart Gill and Behdad Esfahbod.
      *
    @@ -239,7 +239,7 @@
           *e = FT_THROW( Invalid_Stream_Read );
           png_error( png, NULL );
     
    -      return;
    +      /* return; (never reached) */
         }
     
         ft_memcpy( data, stream->cursor, length );
    @@ -407,7 +407,8 @@
         switch ( color_type )
         {
         default:
    -      /* Shouldn't happen, but fall through. */
    +      /* Shouldn't happen, but ... */
    +      FALL_THROUGH;
     
         case PNG_COLOR_TYPE_RGB_ALPHA:
           png_set_read_user_transform_fn( png, premultiply_data );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   PNG Bitmap glyph support.
      *
    - * Copyright (C) 2013-2022 by
    + * Copyright (C) 2013-2023 by
      * Google, Inc.
      * Written by Stuart Gill and Behdad Esfahbod.
      *
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level SFNT driver interface (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -378,61 +378,61 @@
           {
           case 15:
             k4 ^= (FT_UInt32)tail[14] << 16;
    -        /* fall through */
    +        FALL_THROUGH;
           case 14:
             k4 ^= (FT_UInt32)tail[13] << 8;
    -        /* fall through */
    +        FALL_THROUGH;
           case 13:
             k4 ^= (FT_UInt32)tail[12];
             k4 *= c4;
             k4  = ROTL32( k4, 18 );
             k4 *= c1;
             h4 ^= k4;
    -        /* fall through */
    +        FALL_THROUGH;
     
           case 12:
             k3 ^= (FT_UInt32)tail[11] << 24;
    -        /* fall through */
    +        FALL_THROUGH;
           case 11:
             k3 ^= (FT_UInt32)tail[10] << 16;
    -        /* fall through */
    +        FALL_THROUGH;
           case 10:
             k3 ^= (FT_UInt32)tail[9] << 8;
    -        /* fall through */
    +        FALL_THROUGH;
           case 9:
             k3 ^= (FT_UInt32)tail[8];
             k3 *= c3;
             k3  = ROTL32( k3, 17 );
             k3 *= c4;
             h3 ^= k3;
    -        /* fall through */
    +        FALL_THROUGH;
     
           case 8:
             k2 ^= (FT_UInt32)tail[7] << 24;
    -        /* fall through */
    +        FALL_THROUGH;
           case 7:
             k2 ^= (FT_UInt32)tail[6] << 16;
    -        /* fall through */
    +        FALL_THROUGH;
           case 6:
             k2 ^= (FT_UInt32)tail[5] << 8;
    -        /* fall through */
    +        FALL_THROUGH;
           case 5:
             k2 ^= (FT_UInt32)tail[4];
             k2 *= c2;
             k2  = ROTL32( k2, 16 );
             k2 *= c3;
             h2 ^= k2;
    -        /* fall through */
    +        FALL_THROUGH;
     
           case 4:
             k1 ^= (FT_UInt32)tail[3] << 24;
    -        /* fall through */
    +        FALL_THROUGH;
           case 3:
             k1 ^= (FT_UInt32)tail[2] << 16;
    -        /* fall through */
    +        FALL_THROUGH;
           case 2:
             k1 ^= (FT_UInt32)tail[1] << 8;
    -        /* fall through */
    +        FALL_THROUGH;
           case 1:
             k1 ^= (FT_UInt32)tail[0];
             k1 *= c1;
    @@ -657,7 +657,7 @@
     
     
       /*
    -   * Find the shortest decimal representation of a 16.16 fixed point
    +   * Find the shortest decimal representation of a 16.16 fixed-point
        * number.  The function fills `buf' with the result, returning a pointer
        * to the position after the representation's last byte.
        */
    @@ -733,7 +733,7 @@
             an equivalent representation of `fixed'.
     
             The above FOR loop always finds the larger of the two values; I
    -        verified this by iterating over all possible fixed point numbers.
    +        verified this by iterating over all possible fixed-point numbers.
     
             If the remainder is 17232*10, both values are equally good, and we
             take the next even number (following IEEE 754's `round to nearest,
    @@ -741,7 +741,7 @@
     
             If the remainder is smaller than 17232*10, the lower of the two
             numbers is nearer to the exact result (values 17232 and 34480 were
    -        also found by testing all possible fixed point values).
    +        also found by testing all possible fixed-point values).
     
             We use this to find a shorter decimal representation.  If not ending
             with digit zero, we take the representation with less error.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level SFNT driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sferrors.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   SFNT error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   SFNT object management (base).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1107,13 +1107,7 @@
           /* Don't bother to load the tables unless somebody asks for them. */
           /* No need to do work which will (probably) not be used.          */
           if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
    -      {
    -        if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
    -             tt_face_lookup_table( face, TTAG_gvar ) != 0 )
    -          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
    -        if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 )
    -          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
    -      }
    +        flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
     #endif
     
           root->face_flags = flags;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   SFNT object management (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   WOFF2 format management (base).
      *
    - * Copyright (C) 2019-2022 by
    + * Copyright (C) 2019-2023 by
      * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -229,9 +229,9 @@
         {
           FT_TRACE6(( "Reallocating %lu to %lu.\n",
                       *dst_size, (*offset + size) ));
    -      if ( FT_REALLOC( dst,
    -                       (FT_ULong)( *dst_size ),
    -                       (FT_ULong)( *offset + size ) ) )
    +      if ( FT_QREALLOC( dst,
    +                        (FT_ULong)( *dst_size ),
    +                        (FT_ULong)( *offset + size ) ) )
             goto Exit;
     
           *dst_size = *offset + size;
    @@ -784,7 +784,7 @@
           goto Fail;
     
         loca_buf_size = loca_values_size * offset_size;
    -    if ( FT_QNEW_ARRAY( loca_buf, loca_buf_size ) )
    +    if ( FT_QALLOC( loca_buf, loca_buf_size ) )
           goto Fail;
     
         dst = loca_buf;
    @@ -863,7 +863,7 @@
         WOFF2_Point  points       = NULL;
     
     
    -    if ( FT_NEW_ARRAY( substreams, num_substreams ) )
    +    if ( FT_QNEW_ARRAY( substreams, num_substreams ) )
           goto Fail;
     
         if ( FT_STREAM_SKIP( 2 ) )
    @@ -926,7 +926,7 @@
           offset += overlap_bitmap_length;
         }
     
    -    if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) )
    +    if ( FT_QNEW_ARRAY( loca_values, num_glyphs + 1 ) )
           goto Fail;
     
         points_size        = 0;
    @@ -938,10 +938,10 @@
         substreams[BBOX_STREAM].offset += bbox_bitmap_length;
     
         glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
    -    if ( FT_NEW_ARRAY( glyph_buf, glyph_buf_size ) )
    +    if ( FT_QALLOC( glyph_buf, glyph_buf_size ) )
           goto Fail;
     
    -    if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
    +    if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
           goto Fail;
     
         for ( i = 0; i < num_glyphs; ++i )
    @@ -999,7 +999,7 @@
             size_needed = 12 + composite_size + instruction_size;
             if ( glyph_buf_size < size_needed )
             {
    -          if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
    +          if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
                 goto Fail;
               glyph_buf_size = size_needed;
             }
    @@ -1075,7 +1075,7 @@
                 have_overlap = TRUE;
             }
     
    -        if ( FT_NEW_ARRAY( n_points_arr, n_contours ) )
    +        if ( FT_QNEW_ARRAY( n_points_arr, n_contours ) )
               goto Fail;
     
             if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
    @@ -1112,7 +1112,7 @@
     
             /* Create array to store point information. */
             points_size = total_n_points;
    -        if ( FT_NEW_ARRAY( points, points_size ) )
    +        if ( FT_QNEW_ARRAY( points, points_size ) )
               goto Fail;
     
             if ( triplet_decode( flags_buf,
    @@ -1141,7 +1141,7 @@
                           instruction_size;
             if ( glyph_buf_size < size_needed )
             {
    -          if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
    +          if ( FT_QREALLOC( glyph_buf, glyph_buf_size, size_needed ) )
                 goto Fail;
               glyph_buf_size = size_needed;
             }
    @@ -1226,8 +1226,7 @@
           *glyf_checksum += compute_ULong_sum( glyph_buf, glyph_size );
     
           /* Store x_mins, may be required to reconstruct `hmtx'. */
    -      if ( n_contours > 0 )
    -        info->x_mins[i] = (FT_Short)x_min;
    +      info->x_mins[i] = (FT_Short)x_min;
         }
     
         info->glyf_table->dst_length = dest_offset - info->glyf_table->dst_offset;
    @@ -1344,7 +1343,7 @@
         offset_size = index_format ? 4 : 2;
     
         /* Create `x_mins' array. */
    -    if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
    +    if ( FT_QNEW_ARRAY( info->x_mins, num_glyphs ) )
           return error;
     
         loca_offset = info->loca_table->src_offset;
    @@ -1432,8 +1431,8 @@
         if ( num_hmetrics < 1 )
           goto Fail;
     
    -    if ( FT_NEW_ARRAY( advance_widths, num_hmetrics ) ||
    -         FT_NEW_ARRAY( lsbs, num_glyphs )             )
    +    if ( FT_QNEW_ARRAY( advance_widths, num_hmetrics ) ||
    +         FT_QNEW_ARRAY( lsbs, num_glyphs )             )
           goto Fail;
     
         /* Read `advanceWidth' stream.  Always present. */
    @@ -1484,7 +1483,7 @@
     
         /* Build the hmtx table. */
         hmtx_table_size = 2 * num_hmetrics + 2 * num_glyphs;
    -    if ( FT_NEW_ARRAY( hmtx_table, hmtx_table_size ) )
    +    if ( FT_QALLOC( hmtx_table, hmtx_table_size ) )
           goto Fail;
     
         dst = hmtx_table;
    @@ -1541,10 +1540,10 @@
       {
         /* Memory management of `transformed_buf' is handled by the caller. */
     
    -    FT_Error   error       = FT_Err_Ok;
    -    FT_Stream  stream      = NULL;
    -    FT_Byte*   buf_cursor  = NULL;
    -    FT_Byte*   table_entry = NULL;
    +    FT_Error   error      = FT_Err_Ok;
    +    FT_Stream  stream     = NULL;
    +    FT_Byte*   buf_cursor = NULL;
    +    FT_Byte    table_entry[16];
     
         /* We are reallocating memory for `sfnt', so its pointer may change. */
         FT_Byte*   sfnt = *sfnt_bytes;
    @@ -1585,10 +1584,6 @@
           }
         }
     
    -    /* Create buffer for table entries. */
    -    if ( FT_NEW_ARRAY( table_entry, 16 ) )
    -      goto Fail;
    -
         /* Create a stream for the uncompressed buffer. */
         if ( FT_NEW( stream ) )
           goto Fail;
    @@ -1751,7 +1746,6 @@
         /* Set pointer of sfnt stream to its correct value. */
         *sfnt_bytes = sfnt;
     
    -    FT_FREE( table_entry );
         FT_Stream_Close( stream );
         FT_FREE( stream );
     
    @@ -1764,7 +1758,6 @@
         /* Set pointer of sfnt stream to its correct value. */
         *sfnt_bytes = sfnt;
     
    -    FT_FREE( table_entry );
         FT_Stream_Close( stream );
         FT_FREE( stream );
     
    @@ -1877,8 +1870,8 @@
         woff2.ttc_fonts = NULL;
     
         /* Read table directory. */
    -    if ( FT_NEW_ARRAY( tables, woff2.num_tables )  ||
    -         FT_NEW_ARRAY( indices, woff2.num_tables ) )
    +    if ( FT_QNEW_ARRAY( tables, woff2.num_tables )  ||
    +         FT_QNEW_ARRAY( indices, woff2.num_tables ) )
           goto Exit;
     
         FT_TRACE2(( "\n" ));
    @@ -1949,10 +1942,11 @@
             goto Exit;
           }
     
    +      table->flags      = flags;
           table->src_offset = src_offset;
           table->src_length = table->TransformLength;
           src_offset       += table->TransformLength;
    -      table->flags      = flags;
    +      table->dst_offset = 0;
     
           FT_TRACE2(( "  %c%c%c%c  %08d  %08d   %08ld    %08ld    %08ld\n",
                       (FT_Char)( table->Tag >> 24 ),
    @@ -2010,6 +2004,7 @@
     
           FT_TRACE4(( "Number of fonts in TTC: %d\n", woff2.num_fonts ));
     
    +      /* pre-zero pointers within in case of failure */
           if ( FT_NEW_ARRAY( woff2.ttc_fonts, woff2.num_fonts ) )
             goto Exit;
     
    @@ -2023,7 +2018,7 @@
             if ( FT_READ_ULONG( ttc_font->flavor ) )
               goto Exit;
     
    -        if ( FT_NEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
    +        if ( FT_QNEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
               goto Exit;
     
             FT_TRACE5(( "Number of tables in font %d: %d\n",
    @@ -2302,9 +2297,9 @@
         {
           FT_TRACE5(( "Trimming sfnt stream from %lu to %lu.\n",
                       sfnt_size, woff2.actual_sfnt_size ));
    -      if ( FT_REALLOC( sfnt,
    -                       (FT_ULong)( sfnt_size ),
    -                       (FT_ULong)( woff2.actual_sfnt_size ) ) )
    +      if ( FT_QREALLOC( sfnt,
    +                        (FT_ULong)( sfnt_size ),
    +                        (FT_ULong)( woff2.actual_sfnt_size ) ) )
             goto Exit;
         }
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   WOFFF2 format management (specification).
      *
    - * Copyright (C) 2019-2022 by
    + * Copyright (C) 2019-2023 by
      * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   WOFF format management (base).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -162,8 +162,7 @@
         }
     
         /* Don't trust `totalSfntSize' before thorough checks. */
    -    if ( FT_QALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
    -         FT_NEW( sfnt_stream )                          )
    +    if ( FT_QALLOC( sfnt, 12 ) || FT_NEW( sfnt_stream ) )
           goto Exit;
     
         sfnt_header = sfnt;
    @@ -196,8 +195,8 @@
         /* tag value, the tables themselves are not.  We thus have to */
         /* sort them by offset and check that they don't overlap.     */
     
    -    if ( FT_NEW_ARRAY( tables, woff.num_tables )  ||
    -         FT_NEW_ARRAY( indices, woff.num_tables ) )
    +    if ( FT_QNEW_ARRAY( tables, woff.num_tables )  ||
    +         FT_QNEW_ARRAY( indices, woff.num_tables ) )
           goto Exit;
     
         FT_TRACE2(( "\n" ));
    @@ -328,9 +327,7 @@
         }
     
         /* Now use `totalSfntSize'. */
    -    if ( FT_REALLOC( sfnt,
    -                     12 + woff.num_tables * 16UL,
    -                     woff.totalSfntSize ) )
    +    if ( FT_QREALLOC( sfnt, 12, woff.totalSfntSize ) )
           goto Exit;
     
         sfnt_header = sfnt + 12;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   WOFFF format management (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType character mapping table (cmap) support (body).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -3879,13 +3879,14 @@
       }
     
     
    -  FT_LOCAL( FT_Error )
    +  FT_LOCAL_DEF( FT_Error )
       tt_get_cmap_info( FT_CharMap    charmap,
                         TT_CMapInfo  *cmap_info )
       {
         FT_CMap        cmap  = (FT_CMap)charmap;
         TT_CMap_Class  clazz = (TT_CMap_Class)cmap->clazz;
     
    +
         if ( clazz->get_cmap_info )
           return clazz->get_cmap_info( charmap, cmap_info );
         else
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmapc.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TT CMAP classes definitions (specification only).
      *
    - * Copyright (C) 2009-2022 by
    + * Copyright (C) 2009-2023 by
      * Oran Agra and Mickey Gabel.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType character mapping table (cmap) support (specification).
      *
    - * Copyright (C) 2002-2022 by
    + * Copyright (C) 2002-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType and OpenType colored glyph layer support (body).
      *
    - * Copyright (C) 2018-2022 by
    + * Copyright (C) 2018-2023 by
      * David Turner, Robert Wilhelm, Dominik Röttsches, and Werner Lemberg.
      *
      * Originally written by Shao Yu Zhang .
    @@ -34,6 +34,9 @@
     #include 
     #include 
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +#include 
    +#endif
     
     #ifdef TT_CONFIG_OPTION_COLOR_LAYERS
     
    @@ -46,17 +49,42 @@
     #define LAYER_V1_LIST_PAINT_OFFSET_SIZE   4U
     #define LAYER_V1_LIST_NUM_LAYERS_SIZE     4U
     #define COLOR_STOP_SIZE                   6U
    +#define VAR_IDX_BASE_SIZE                 4U
     #define LAYER_SIZE                        4U
    -#define COLR_HEADER_SIZE                 14U
    +/* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#colr-header */
    +/* 3 * uint16 + 2 * Offset32 */
    +#define COLRV0_HEADER_SIZE               14U
    +/* COLRV0_HEADER_SIZE + 5 * Offset32 */
    +#define COLRV1_HEADER_SIZE               34U
    +
    +
    +#define ENSURE_READ_BYTES( byte_size )                             \
    +  if ( p < colr->paints_start_v1                                || \
    +       p > (FT_Byte*)colr->table + colr->table_size - byte_size )  \
    +    return 0
     
     
       typedef enum  FT_PaintFormat_Internal_
       {
    -    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER         = 18,
    -    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM        = 20,
    -    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER = 22,
    -    FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER        = 26,
    -    FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER          = 30
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID                = 3,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT      = 5,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT      = 7,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT       = 9,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM            = 13,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE            = 15,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE                = 17,
    +    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER             = 18,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER         = 19,
    +    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM            = 20,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM        = 21,
    +    FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER     = 22,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER = 23,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE               = 25,
    +    FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER            = 26,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER        = 27,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW                 = 29,
    +    FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER              = 30,
    +    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER          = 31,
     
       } FT_PaintFormat_Internal;
     
    @@ -104,6 +132,12 @@
          */
         FT_Byte*  paints_start_v1;
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +    /* Item Variation Store for variable 'COLR' v1. */
    +    GX_ItemVarStoreRec    var_store;
    +    GX_DeltaSetIdxMapRec  delta_set_idx_map;
    +#endif
    +
         /* The memory that backs up the `COLR' table. */
         void*     table;
         FT_ULong  table_size;
    @@ -139,6 +173,9 @@
         FT_ULong  base_glyphs_offset_v1, num_base_glyphs_v1;
         FT_ULong  layer_offset_v1, num_layers_v1, clip_list_offset;
         FT_ULong  table_size;
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +    FT_ULong  colr_offset_in_stream;
    +#endif
     
     
         /* `COLR' always needs `CPAL' */
    @@ -149,8 +186,12 @@
         if ( error )
           goto NoColr;
     
    -    if ( table_size < COLR_HEADER_SIZE )
    -      goto InvalidTable;
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +    colr_offset_in_stream = FT_STREAM_POS();
    +#endif
    +
    +    if ( table_size < COLRV0_HEADER_SIZE )
    +      goto NoColr;
     
         if ( FT_FRAME_EXTRACT( table_size, table ) )
           goto NoColr;
    @@ -183,9 +224,12 @@
     
         if ( colr->version == 1 )
         {
    +      if ( table_size < COLRV1_HEADER_SIZE )
    +        goto InvalidTable;
    +
           base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
     
    -      if ( base_glyphs_offset_v1 >= table_size )
    +      if ( base_glyphs_offset_v1 + 4 >= table_size )
             goto InvalidTable;
     
           p1                 = (FT_Byte*)( table + base_glyphs_offset_v1 );
    @@ -205,6 +249,9 @@
     
           if ( layer_offset_v1 )
           {
    +        if ( layer_offset_v1 + 4 >= table_size )
    +          goto InvalidTable;
    +
             p1            = (FT_Byte*)( table + layer_offset_v1 );
             num_layers_v1 = FT_PEEK_ULONG( p1 );
     
    @@ -239,6 +286,65 @@
             colr->clip_list = (FT_Byte*)( table + clip_list_offset );
           else
             colr->clip_list = 0;
    +
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      colr->var_store.dataCount     = 0;
    +      colr->var_store.varData       = NULL;
    +      colr->var_store.axisCount     = 0;
    +      colr->var_store.regionCount   = 0;
    +      colr->var_store.varRegionList = 0;
    +
    +      colr->delta_set_idx_map.mapCount   = 0;
    +      colr->delta_set_idx_map.outerIndex = NULL;
    +      colr->delta_set_idx_map.innerIndex = NULL;
    +
    +      if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
    +      {
    +        FT_ULong  var_idx_map_offset, var_store_offset;
    +
    +        FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +        var_idx_map_offset = FT_NEXT_ULONG( p );
    +
    +        if ( var_idx_map_offset >= table_size )
    +          goto InvalidTable;
    +
    +        var_store_offset = FT_NEXT_ULONG( p );
    +        if ( var_store_offset >= table_size )
    +          goto InvalidTable;
    +
    +        if ( var_store_offset )
    +        {
    +          /* If variation info has not been initialized yet, try doing so, */
    +          /* otherwise loading the variation store will fail as it         */
    +          /* requires access to `blend` for checking the number of axes.   */
    +          if ( !face->blend )
    +            if ( mm->get_mm_var( FT_FACE( face ), NULL ) )
    +              goto InvalidTable;
    +
    +          /* Try loading `VarIdxMap` and `VarStore`. */
    +          error = mm->load_item_var_store(
    +                    FT_FACE( face ),
    +                    colr_offset_in_stream + var_store_offset,
    +                    &colr->var_store );
    +          if ( error != FT_Err_Ok )
    +            goto InvalidTable;
    +        }
    +
    +        if ( colr->var_store.axisCount && var_idx_map_offset )
    +        {
    +          error = mm->load_delta_set_idx_map(
    +                    FT_FACE( face ),
    +                    colr_offset_in_stream + var_idx_map_offset,
    +                    &colr->delta_set_idx_map,
    +                    &colr->var_store,
    +                    table_size );
    +          if ( error != FT_Err_Ok )
    +            goto InvalidTable;
    +        }
    +      }
    +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
         }
     
         colr->base_glyphs = (FT_Byte*)( table + base_glyph_offset );
    @@ -251,6 +357,18 @@
         return FT_Err_Ok;
     
       InvalidTable:
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +    {
    +      FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +      mm->done_delta_set_idx_map( FT_FACE( face ),
    +                                  &colr->delta_set_idx_map );
    +      mm->done_item_var_store( FT_FACE( face ),
    +                               &colr->var_store );
    +    }
    +#endif
    +
         error = FT_THROW( Invalid_Table );
     
       NoColr:
    @@ -272,6 +390,17 @@
     
         if ( colr )
         {
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      {
    +        FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +
    +        mm->done_delta_set_idx_map( FT_FACE( face ),
    +                                    &colr->delta_set_idx_map );
    +        mm->done_item_var_store( FT_FACE( face ),
    +                                 &colr->var_store );
    +      }
    +#endif
           FT_FRAME_RELEASE( colr->table );
           FT_FREE( colr );
         }
    @@ -354,7 +483,9 @@
           iterator->p = colr->layers + offset;
         }
     
    -    if ( iterator->layer >= iterator->num_layers )
    +    if ( iterator->layer >= iterator->num_layers                     ||
    +         iterator->p < colr->layers                                  ||
    +         iterator->p >= ( (FT_Byte*)colr->table + colr->table_size ) )
           return 0;
     
         *aglyph_index = FT_NEXT_USHORT( iterator->p );
    @@ -372,13 +503,17 @@
     
     
       static FT_Bool
    -  read_color_line( FT_Byte*      color_line_p,
    -                   FT_ColorLine  *colorline )
    +  read_color_line( Colr*          colr,
    +                   FT_Byte*       color_line_p,
    +                   FT_ColorLine*  colorline,
    +                   FT_Bool        read_variable )
       {
         FT_Byte*        p = color_line_p;
         FT_PaintExtend  paint_extend;
     
     
    +    ENSURE_READ_BYTES( 3 );
    +
         paint_extend = (FT_PaintExtend)FT_NEXT_BYTE( p );
         if ( paint_extend > FT_COLR_PAINT_EXTEND_REFLECT )
           return 0;
    @@ -388,6 +523,7 @@
         colorline->color_stop_iterator.num_color_stops    = FT_NEXT_USHORT( p );
         colorline->color_stop_iterator.p                  = p;
         colorline->color_stop_iterator.current_color_stop = 0;
    +    colorline->color_stop_iterator.read_variable      = read_variable;
     
         return 1;
       }
    @@ -413,6 +549,10 @@
         if ( !child_table_pointer )
           return 0;
     
    +    if ( *p < colr->paints_start_v1                            ||
    +         *p > (FT_Byte*)colr->table + colr->table_size - 1 - 3 )
    +      return 0;
    +
         paint_offset = FT_NEXT_UOFF3( *p );
         if ( !paint_offset )
           return 0;
    @@ -428,20 +568,85 @@
       }
     
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +
       static FT_Bool
    -  read_paint( Colr*           colr,
    +  get_deltas_for_var_index_base ( TT_Face           face,
    +                                  Colr*             colr,
    +                                  FT_ULong          var_index_base,
    +                                  FT_UInt           num_deltas,
    +                                  FT_ItemVarDelta*  deltas )
    +  {
    +    FT_UInt   outer_index    = 0;
    +    FT_UInt   inner_index    = 0;
    +    FT_ULong  loop_var_index = var_index_base;
    +
    +    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
    +
    +    FT_UInt  i = 0;
    +
    +
    +    if ( var_index_base == 0xFFFFFFFF )
    +    {
    +      for ( i = 0; i < num_deltas; ++i )
    +        deltas[i] = 0;
    +      return 1;
    +    }
    +
    +    for ( i = 0; i < num_deltas; ++i )
    +    {
    +      loop_var_index = var_index_base + i;
    +
    +      if ( colr->delta_set_idx_map.innerIndex )
    +      {
    +        if ( loop_var_index >= colr->delta_set_idx_map.mapCount )
    +          loop_var_index = colr->delta_set_idx_map.mapCount - 1;
    +
    +        outer_index = colr->delta_set_idx_map.outerIndex[loop_var_index];
    +        inner_index = colr->delta_set_idx_map.innerIndex[loop_var_index];
    +      }
    +      else
    +      {
    +        outer_index = 0;
    +        inner_index = loop_var_index;
    +      }
    +
    +      deltas[i] = mm->get_item_delta( FT_FACE( face ), &colr->var_store,
    +                                      outer_index, inner_index );
    +    }
    +
    +    return 1;
    +  }
    +
    +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
    +
    +
    +  static FT_Bool
    +  read_paint( TT_Face         face,
    +              Colr*           colr,
                   FT_Byte*        p,
                   FT_COLR_Paint*  apaint )
       {
    -    FT_Byte*  paint_base     = p;
    -    FT_Byte*  child_table_p  = NULL;
    +    FT_Byte*  paint_base    = p;
    +    FT_Byte*  child_table_p = NULL;
    +    FT_Bool   do_read_var   = FALSE;
    +
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +    FT_ULong         var_index_base = 0;
    +    /* Longest varIndexBase offset is 5 in the spec. */
    +    FT_ItemVarDelta  item_deltas[6] = { 0, 0, 0, 0, 0, 0 };
    +#else
    +    FT_UNUSED( face );
    +#endif
     
     
         if ( !p || !colr || !colr->table )
           return 0;
     
    -    if ( p < colr->paints_start_v1                         ||
    -         p >= ( (FT_Byte*)colr->table + colr->table_size ) )
    +    /* The last byte of the 'COLR' table is at 'size-1'; subtract 1 of    */
    +    /* that to account for the expected format byte we are going to read. */
    +    if ( p < colr->paints_start_v1                        ||
    +         p > (FT_Byte*)colr->table + colr->table_size - 2 )
           return 0;
     
         apaint->format = (FT_PaintFormat)FT_NEXT_BYTE( p );
    @@ -475,16 +680,37 @@
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID )
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_SOLID ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                 FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID   )
         {
    +      ENSURE_READ_BYTES( 4 );
           apaint->u.solid.color.palette_index = FT_NEXT_USHORT( p );
           apaint->u.solid.color.alpha         = FT_NEXT_SHORT( p );
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( (FT_PaintFormat_Internal)apaint->format ==
    +              FT_COLR_PAINTFORMAT_INTERNAL_VAR_SOLID )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG( p );
    +
    +        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        apaint->u.solid.color.alpha += item_deltas[0];
    +      }
    +#endif
    +
    +      apaint->format = FT_COLR_PAINTFORMAT_SOLID;
    +
           return 1;
         }
     
         else if ( apaint->format == FT_COLR_PAINTFORMAT_COLR_GLYPH )
         {
    +      ENSURE_READ_BYTES(2);
           apaint->u.colr_glyph.glyphID = FT_NEXT_USHORT( p );
     
           return 1;
    @@ -500,16 +726,23 @@
         if ( !get_child_table_pointer( colr, paint_base, &p, &child_table_p ) )
           return 0;
     
    -    if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT )
    +    if ( apaint->format == FT_COLR_PAINTFORMAT_LINEAR_GRADIENT      ||
    +         ( do_read_var =
    +             ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_LINEAR_GRADIENT ) ) )
         {
    -      if ( !read_color_line( child_table_p,
    -                             &apaint->u.linear_gradient.colorline ) )
    +      if ( !read_color_line( colr,
    +                             child_table_p,
    +                             &apaint->u.linear_gradient.colorline,
    +                             do_read_var ) )
             return 0;
     
           /*
    -       * In order to support variations expose these as FT_Fixed 16.16 values so
    -       * that we can support fractional values after interpolation.
    +       * In order to support variations expose these as FT_Fixed 16.16
    +       * values so that we can support fractional values after
    +       * interpolation.
            */
    +      ENSURE_READ_BYTES( 12 );
           apaint->u.linear_gradient.p0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.linear_gradient.p0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.linear_gradient.p1.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
    @@ -517,23 +750,52 @@
           apaint->u.linear_gradient.p2.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.linear_gradient.p2.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( do_read_var )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG ( p );
    +
    +        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        apaint->u.linear_gradient.p0.x += INT_TO_FIXED( item_deltas[0] );
    +        apaint->u.linear_gradient.p0.y += INT_TO_FIXED( item_deltas[1] );
    +        apaint->u.linear_gradient.p1.x += INT_TO_FIXED( item_deltas[2] );
    +        apaint->u.linear_gradient.p1.y += INT_TO_FIXED( item_deltas[3] );
    +        apaint->u.linear_gradient.p2.x += INT_TO_FIXED( item_deltas[4] );
    +        apaint->u.linear_gradient.p2.y += INT_TO_FIXED( item_deltas[5] );
    +      }
    +#endif
    +
    +      apaint->format = FT_COLR_PAINTFORMAT_LINEAR_GRADIENT;
    +
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT )
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_RADIAL_GRADIENT      ||
    +              ( do_read_var =
    +                  ( (FT_PaintFormat_Internal)apaint->format ==
    +                    FT_COLR_PAINTFORMAT_INTERNAL_VAR_RADIAL_GRADIENT ) ) )
         {
           FT_Pos  tmp;
     
     
    -      if ( !read_color_line( child_table_p,
    -                             &apaint->u.radial_gradient.colorline ) )
    +      if ( !read_color_line( colr,
    +                             child_table_p,
    +                             &apaint->u.radial_gradient.colorline,
    +                             do_read_var ) )
             return 0;
     
    +
           /* In the OpenType specification, `r0` and `r1` are defined as   */
           /* `UFWORD`.  Since FreeType doesn't have a corresponding 16.16  */
           /* format we convert to `FWORD` and replace negative values with */
           /* (32bit) `FT_INT_MAX`.                                         */
     
    +      ENSURE_READ_BYTES( 12 );
    +
           apaint->u.radial_gradient.c0.x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.radial_gradient.c0.y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
     
    @@ -546,15 +808,47 @@
           tmp                          = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.radial_gradient.r1 = tmp < 0 ? FT_INT_MAX : tmp;
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( do_read_var )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG ( p );
    +
    +        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        apaint->u.radial_gradient.c0.x += INT_TO_FIXED( item_deltas[0] );
    +        apaint->u.radial_gradient.c0.y += INT_TO_FIXED( item_deltas[1] );
    +
    +        // TODO: Anything to be done about UFWORD deltas here?
    +        apaint->u.radial_gradient.r0 += INT_TO_FIXED( item_deltas[2] );
    +
    +        apaint->u.radial_gradient.c1.x += INT_TO_FIXED( item_deltas[3] );
    +        apaint->u.radial_gradient.c1.y += INT_TO_FIXED( item_deltas[4] );
    +
    +        apaint->u.radial_gradient.r1 += INT_TO_FIXED( item_deltas[5] );
    +      }
    +#endif
    +
    +      apaint->format = FT_COLR_PAINTFORMAT_RADIAL_GRADIENT;
    +
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT )
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_SWEEP_GRADIENT      ||
    +              ( do_read_var =
    +                  ( (FT_PaintFormat_Internal)apaint->format ==
    +                    FT_COLR_PAINTFORMAT_INTERNAL_VAR_SWEEP_GRADIENT ) ) )
         {
    -      if ( !read_color_line( child_table_p,
    -                             &apaint->u.sweep_gradient.colorline ) )
    +      if ( !read_color_line( colr,
    +                             child_table_p,
    +                             &apaint->u.sweep_gradient.colorline,
    +                             do_read_var) )
             return 0;
     
    +      ENSURE_READ_BYTES( 8 );
    +
           apaint->u.sweep_gradient.center.x =
               INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.sweep_gradient.center.y =
    @@ -565,11 +859,34 @@
           apaint->u.sweep_gradient.end_angle =
               F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( do_read_var )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG ( p );
    +
    +        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        // TODO: Handle overflow?
    +        apaint->u.sweep_gradient.center.x += INT_TO_FIXED( item_deltas[0] );
    +        apaint->u.sweep_gradient.center.y += INT_TO_FIXED( item_deltas[1] );
    +
    +        apaint->u.sweep_gradient.start_angle +=
    +          F2DOT14_TO_FIXED( item_deltas[2] );
    +        apaint->u.sweep_gradient.end_angle +=
    +          F2DOT14_TO_FIXED( item_deltas[3] );
    +      }
    +#endif
    +      apaint->format = FT_COLR_PAINTFORMAT_SWEEP_GRADIENT;
    +
           return 1;
         }
     
         if ( apaint->format == FT_COLR_PAINTFORMAT_GLYPH )
         {
    +      ENSURE_READ_BYTES( 2 );
           apaint->u.glyph.paint.p                     = child_table_p;
           apaint->u.glyph.paint.insert_root_transform = 0;
           apaint->u.glyph.glyphID                     = FT_NEXT_USHORT( p );
    @@ -577,7 +894,9 @@
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM )
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSFORM ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM    )
         {
           apaint->u.transform.paint.p                     = child_table_p;
           apaint->u.transform.paint.insert_root_transform = 0;
    @@ -591,6 +910,7 @@
            * The following matrix coefficients are encoded as
            * OpenType 16.16 fixed-point values.
            */
    +      ENSURE_READ_BYTES( 24 );
           apaint->u.transform.affine.xx = FT_NEXT_LONG( p );
           apaint->u.transform.affine.yx = FT_NEXT_LONG( p );
           apaint->u.transform.affine.xy = FT_NEXT_LONG( p );
    @@ -598,51 +918,101 @@
           apaint->u.transform.affine.dx = FT_NEXT_LONG( p );
           apaint->u.transform.affine.dy = FT_NEXT_LONG( p );
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSFORM )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG( p );
    +
    +        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 6,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        apaint->u.transform.affine.xx += (FT_Fixed)item_deltas[0];
    +        apaint->u.transform.affine.yx += (FT_Fixed)item_deltas[1];
    +        apaint->u.transform.affine.xy += (FT_Fixed)item_deltas[2];
    +        apaint->u.transform.affine.yy += (FT_Fixed)item_deltas[3];
    +        apaint->u.transform.affine.dx += (FT_Fixed)item_deltas[4];
    +        apaint->u.transform.affine.dy += (FT_Fixed)item_deltas[5];
    +      }
    +#endif
    +
    +      apaint->format = FT_COLR_PAINTFORMAT_TRANSFORM;
    +
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE )
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_TRANSLATE ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE    )
         {
           apaint->u.translate.paint.p                     = child_table_p;
           apaint->u.translate.paint.insert_root_transform = 0;
     
    +      ENSURE_READ_BYTES( 4 );
           apaint->u.translate.dx = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.translate.dy = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_TRANSLATE )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG( p );
    +
    +        if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        apaint->u.translate.dx += INT_TO_FIXED( item_deltas[0] );
    +        apaint->u.translate.dy += INT_TO_FIXED( item_deltas[1] );
    +      }
    +#endif
    +
    +      apaint->format = FT_COLR_PAINTFORMAT_TRANSLATE;
    +
           return 1;
         }
     
    -    else if ( apaint->format ==
    -                FT_COLR_PAINTFORMAT_SCALE                         ||
    -              (FT_PaintFormat_Internal)apaint->format ==
    -                FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER         ||
    -              (FT_PaintFormat_Internal)apaint->format ==
    -                FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM        ||
    -              (FT_PaintFormat_Internal)apaint->format ==
    -                FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
    +    else if ( apaint->format >= FT_COLR_PAINTFORMAT_SCALE             &&
    +              (FT_PaintFormat_Internal)apaint->format <=
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
         {
           apaint->u.scale.paint.p                     = child_table_p;
           apaint->u.scale.paint.insert_root_transform = 0;
     
           /* All scale paints get at least one scale value. */
    +      ENSURE_READ_BYTES( 2 );
           apaint->u.scale.scale_x = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
     
           /* Non-uniform ones read an extra y value. */
    -      if ( apaint->format ==
    -             FT_COLR_PAINTFORMAT_SCALE                 ||
    +      if ( apaint->format == FT_COLR_PAINTFORMAT_SCALE     ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE        ||
                (FT_PaintFormat_Internal)apaint->format ==
    -             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER )
    +             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER     ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
    +      {
    +        ENSURE_READ_BYTES( 2 );
             apaint->u.scale.scale_y = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
    +      }
           else
             apaint->u.scale.scale_y = apaint->u.scale.scale_x;
     
           /* Scale paints that have a center read center coordinates, */
           /* otherwise the center is (0,0).                           */
           if ( (FT_PaintFormat_Internal)apaint->format ==
    -             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER         ||
    +             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_CENTER             ||
                (FT_PaintFormat_Internal)apaint->format ==
    -             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER )
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER         ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_SCALE_UNIFORM_CENTER     ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
           {
    +        ENSURE_READ_BYTES( 4 );
             apaint->u.scale.center_x = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
             apaint->u.scale.center_y = INT_TO_FIXED( FT_NEXT_SHORT ( p ) );
           }
    @@ -652,6 +1022,71 @@
             apaint->u.scale.center_y = 0;
           }
     
    +      /* Base values set, now handle variations. */
    +
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE                ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER         ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM        ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG( p );
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[1] );
    +        }
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_CENTER )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          apaint->u.scale.scale_x  += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.scale.scale_y  += F2DOT14_TO_FIXED( item_deltas[1] );
    +          apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[2] );
    +          apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[3] );
    +        }
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 1,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          apaint->u.scale.scale_x += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.scale.scale_y += F2DOT14_TO_FIXED( item_deltas[0] );
    +        }
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SCALE_UNIFORM_CENTER )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 3,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          apaint->u.scale.scale_x  += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.scale.scale_y  += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.scale.center_x += INT_TO_FIXED( item_deltas[1] );
    +          apaint->u.scale.center_y += INT_TO_FIXED( item_deltas[2] );
    +        }
    +      }
    +#endif
    +
           /* FT 'COLR' v1 API output format always returns fully defined */
           /* structs; we thus set the format to the public API value.    */
           apaint->format = FT_COLR_PAINTFORMAT_SCALE;
    @@ -659,18 +1094,26 @@
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE ||
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_ROTATE     ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER     ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE        ||
                   (FT_PaintFormat_Internal)apaint->format ==
    -                FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER )
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
         {
           apaint->u.rotate.paint.p                     = child_table_p;
           apaint->u.rotate.paint.insert_root_transform = 0;
     
    +      ENSURE_READ_BYTES( 2 );
           apaint->u.rotate.angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
     
           if ( (FT_PaintFormat_Internal)apaint->format ==
    -           FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER )
    +             FT_COLR_PAINTFORMAT_INTERNAL_ROTATE_CENTER     ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
           {
    +        ENSURE_READ_BYTES( 4 );
             apaint->u.rotate.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
             apaint->u.rotate.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           }
    @@ -680,24 +1123,69 @@
             apaint->u.rotate.center_y = 0;
           }
     
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE        ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
    +      {
    +        FT_UInt  num_deltas = 0;
    +
    +
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG( p );
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE_CENTER )
    +          num_deltas = 3;
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_ROTATE )
    +          num_deltas = 1;
    +
    +        if ( num_deltas > 0 )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base,
    +                                               num_deltas, item_deltas ) )
    +            return 0;
    +
    +          apaint->u.rotate.angle += F2DOT14_TO_FIXED( item_deltas[0] );
    +
    +          if ( num_deltas == 3 )
    +          {
    +            apaint->u.rotate.center_x += INT_TO_FIXED( item_deltas[1] );
    +            apaint->u.rotate.center_y += INT_TO_FIXED( item_deltas[2] );
    +          }
    +        }
    +      }
    +#endif
    +
           apaint->format = FT_COLR_PAINTFORMAT_ROTATE;
     
    +
           return 1;
         }
     
    -    else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW ||
    +    else if ( apaint->format == FT_COLR_PAINTFORMAT_SKEW     ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW        ||
    +              (FT_PaintFormat_Internal)apaint->format ==
    +                FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER     ||
                   (FT_PaintFormat_Internal)apaint->format ==
    -                FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER )
    +                FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
         {
           apaint->u.skew.paint.p                     = child_table_p;
           apaint->u.skew.paint.insert_root_transform = 0;
     
    +      ENSURE_READ_BYTES( 4 );
           apaint->u.skew.x_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
           apaint->u.skew.y_skew_angle = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
     
           if ( (FT_PaintFormat_Internal)apaint->format ==
    -           FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER )
    +             FT_COLR_PAINTFORMAT_INTERNAL_SKEW_CENTER     ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
           {
    +        ENSURE_READ_BYTES( 4 );
             apaint->u.skew.center_x = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
             apaint->u.skew.center_y = INT_TO_FIXED( FT_NEXT_SHORT( p ) );
           }
    @@ -707,6 +1195,42 @@
             apaint->u.skew.center_y = 0;
           }
     
    +
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      if ( (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW        ||
    +           (FT_PaintFormat_Internal)apaint->format ==
    +             FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
    +      {
    +        ENSURE_READ_BYTES( 4 );
    +        var_index_base = FT_NEXT_ULONG( p );
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 2,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
    +        }
    +
    +        if ( (FT_PaintFormat_Internal)apaint->format ==
    +               FT_COLR_PAINTFORMAT_INTERNAL_VAR_SKEW_CENTER )
    +        {
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          apaint->u.skew.x_skew_angle += F2DOT14_TO_FIXED( item_deltas[0] );
    +          apaint->u.skew.y_skew_angle += F2DOT14_TO_FIXED( item_deltas[1] );
    +          apaint->u.skew.center_x     += INT_TO_FIXED( item_deltas[2] );
    +          apaint->u.skew.center_y     += INT_TO_FIXED( item_deltas[3] );
    +        }
    +      }
    +#endif
    +
           apaint->format = FT_COLR_PAINTFORMAT_SKEW;
     
           return 1;
    @@ -720,6 +1244,7 @@
           apaint->u.composite.source_paint.p                     = child_table_p;
           apaint->u.composite.source_paint.insert_root_transform = 0;
     
    +      ENSURE_READ_BYTES( 1 );
           composite_mode = FT_NEXT_BYTE( p );
           if ( composite_mode >= FT_COLR_COMPOSITE_MAX )
             return 0;
    @@ -871,7 +1396,7 @@
         clip_list_format = FT_NEXT_BYTE ( p );
     
         /* Format byte used here to be able to upgrade ClipList for >16bit */
    -    /* glyph ids; for now we can expect it to be 0.                    */
    +    /* glyph ids; for now we can expect it to be 1.                    */
         if ( !( clip_list_format == 1 ) )
           return 0;
     
    @@ -899,7 +1424,7 @@
     
             format = FT_NEXT_BYTE( p1 );
     
    -        if ( format > 1 )
    +        if ( format > 2 )
               return 0;
     
             /* Check whether we can extract four `FWORD`. */
    @@ -913,11 +1438,40 @@
             font_clip_box.xMin = FT_MulFix( FT_NEXT_SHORT( p1 ),
                                             face->root.size->metrics.x_scale );
             font_clip_box.yMin = FT_MulFix( FT_NEXT_SHORT( p1 ),
    -                                        face->root.size->metrics.x_scale );
    +                                        face->root.size->metrics.y_scale );
             font_clip_box.xMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
                                             face->root.size->metrics.x_scale );
             font_clip_box.yMax = FT_MulFix( FT_NEXT_SHORT( p1 ),
    -                                        face->root.size->metrics.x_scale );
    +                                        face->root.size->metrics.y_scale );
    +
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +        if ( format == 2 )
    +        {
    +          FT_ULong         var_index_base = 0;
    +          /* varIndexBase offset for clipbox is 3 at most. */
    +          FT_ItemVarDelta  item_deltas[4] = { 0, 0, 0, 0 };
    +
    +
    +          /* Check whether we can extract a 32-bit varIndexBase now. */
    +          if ( p1 > limit - 4 )
    +            return 0;
    +
    +          var_index_base = FT_NEXT_ULONG( p1 );
    +
    +          if ( !get_deltas_for_var_index_base( face, colr, var_index_base, 4,
    +                                               item_deltas ) )
    +            return 0;
    +
    +          font_clip_box.xMin +=
    +            FT_MulFix( item_deltas[0], face->root.size->metrics.x_scale );
    +          font_clip_box.yMin +=
    +            FT_MulFix( item_deltas[1], face->root.size->metrics.y_scale );
    +          font_clip_box.xMax +=
    +            FT_MulFix( item_deltas[2], face->root.size->metrics.x_scale );
    +          font_clip_box.yMax +=
    +            FT_MulFix( item_deltas[3], face->root.size->metrics.y_scale );
    +        }
    +#endif
     
             /* Make 4 corner points (xMin, yMin), (xMax, yMax) and transform */
             /* them.  If we we would only transform two corner points and    */
    @@ -986,13 +1540,6 @@
         p = iterator->p;
     
         /*
    -     * First ensure that p is within COLRv1.
    -     */
    -    if ( p < colr->layers_v1                               ||
    -         p >= ( (FT_Byte*)colr->table + colr->table_size ) )
    -      return 0;
    -
    -    /*
          * Do a cursor sanity check of the iterator.  Counting backwards from
          * where it stands, we need to end up at a position after the beginning
          * of the `LayerV1List` table and not after the end of the
    @@ -1008,6 +1555,14 @@
                colr->num_layers_v1 * LAYER_V1_LIST_PAINT_OFFSET_SIZE ) )
           return 0;
     
    +    /*
    +     * Before reading, ensure that `p` is within 'COLR' v1 and we can read a
    +     * 4-byte ULONG.
    +     */
    +    if ( p < colr->layers_v1                              ||
    +         p > (FT_Byte*)colr->table + colr->table_size - 4 )
    +      return 0;
    +
         paint_offset =
           FT_NEXT_ULONG( p );
         opaque_paint->insert_root_transform =
    @@ -1037,29 +1592,67 @@
         Colr*  colr = (Colr*)face->colr;
     
         FT_Byte*  p;
    +    FT_ULong  var_index_base;
    +    FT_Byte*  last_entry_p = NULL;
    +    FT_UInt   entry_size   = COLOR_STOP_SIZE;
     
     
    -    if ( !colr || !colr->table )
    +    if ( !colr || !colr->table || !iterator )
           return 0;
     
         if ( iterator->current_color_stop >= iterator->num_color_stops )
           return 0;
     
    -    if ( iterator->p +
    -           ( ( iterator->num_color_stops - iterator->current_color_stop ) *
    -             COLOR_STOP_SIZE ) >
    -         ( (FT_Byte *)colr->table + colr->table_size ) )
    +    if ( iterator->read_variable )
    +      entry_size += VAR_IDX_BASE_SIZE;
    +
    +    /* Calculate the start pointer for the last to-be-read (Var)ColorStop */
    +    /* and check whether we can read a full (Var)ColorStop at that        */
    +    /* position by comparing it to the position that is the size of one   */
    +    /* (Var)ColorStop before the end of the 'COLR' table.                 */
    +    last_entry_p =
    +      iterator->p + ( iterator->num_color_stops - 1 -
    +                      iterator->current_color_stop ) * entry_size;
    +    if ( iterator->p < colr->paints_start_v1          ||
    +         last_entry_p > (FT_Byte*)colr->table +
    +                        colr->table_size - entry_size )
           return 0;
     
         /* Iterator points at first `ColorStop` of `ColorLine`. */
         p = iterator->p;
     
    -    color_stop->stop_offset = FT_NEXT_SHORT( p );
    +    color_stop->stop_offset = F2DOT14_TO_FIXED( FT_NEXT_SHORT( p ) );
     
         color_stop->color.palette_index = FT_NEXT_USHORT( p );
     
         color_stop->color.alpha = FT_NEXT_SHORT( p );
     
    +    if ( iterator->read_variable )
    +    {
    +      /* Pointer p needs to be advanced independently of whether we intend */
    +      /* to take variable deltas into account or not.  Otherwise iteration */
    +      /* would fail due to wrong offsets.                                  */
    +      var_index_base = FT_NEXT_ULONG( p );
    +
    +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    +      {
    +        FT_Int  item_deltas[2];
    +
    +
    +        if ( !get_deltas_for_var_index_base( face, colr,
    +                                             var_index_base,
    +                                             2,
    +                                             item_deltas ) )
    +          return 0;
    +
    +        color_stop->stop_offset += F2DOT14_TO_FIXED( item_deltas[0] );
    +        color_stop->color.alpha += item_deltas[1];
    +      }
    +#else
    +      FT_UNUSED( var_index_base );
    +#endif
    +    }
    +
         iterator->p = p;
         iterator->current_color_stop++;
     
    @@ -1139,7 +1732,7 @@
           return 1;
         }
     
    -    return read_paint( colr, opaque_paint.p, paint );
    +    return read_paint( face, colr, opaque_paint.p, paint );
       }
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType and OpenType colored glyph layer support (specification).
      *
    - * Copyright (C) 2018-2022 by
    + * Copyright (C) 2018-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * Originally written by Shao Yu Zhang .
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType and OpenType color palette support (body).
      *
    - * Copyright (C) 2018-2022 by
    + * Copyright (C) 2018-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * Originally written by Shao Yu Zhang .
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType and OpenType color palette support (specification).
      *
    - * Copyright (C) 2018-2022 by
    + * Copyright (C) 2018-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * Originally written by Shao Yu Zhang .
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.c	2023-10-06 05:33:33.000000000 +0000
    @@ -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-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttkern.h	2023-10-06 05:33:33.000000000 +0000
    @@ -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-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -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-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -206,7 +206,7 @@
           if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
           {
             FT_TRACE2(( "check_table_dir:"
    -                    " can read only %d table%s in font (instead of %d)\n",
    +                    " can read only %hu table%s in font (instead of %hu)\n",
                         nn, nn == 1 ? "" : "s", sfnt->num_tables ));
             sfnt->num_tables = nn;
             break;
    @@ -216,7 +216,7 @@
     
           if ( table.Offset > stream->size )
           {
    -        FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
    +        FT_TRACE2(( "check_table_dir: table entry %hu invalid\n", nn ));
             continue;
           }
           else if ( table.Length > stream->size - table.Offset )
    @@ -231,7 +231,7 @@
               valid_entries++;
             else
             {
    -          FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
    +          FT_TRACE2(( "check_table_dir: table entry %hu invalid\n", nn ));
               continue;
             }
           }
    @@ -380,7 +380,7 @@
     
         /* load the table directory */
     
    -    FT_TRACE2(( "-- Number of tables: %10u\n",    sfnt.num_tables ));
    +    FT_TRACE2(( "-- Number of tables: %10hu\n",   sfnt.num_tables ));
         FT_TRACE2(( "-- Format version:   0x%08lx\n", sfnt.format_tag ));
     
         if ( sfnt.format_tag != TTAG_OTTO )
    @@ -671,8 +671,8 @@
         if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
           goto Exit;
     
    -    FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
    -    FT_TRACE3(( "IndexToLoc:   %4d\n", header->Index_To_Loc_Format ));
    +    FT_TRACE3(( "Units per EM: %4hu\n", header->Units_Per_EM ));
    +    FT_TRACE3(( "IndexToLoc:   %4hd\n", header->Index_To_Loc_Format ));
     
       Exit:
         return error;
    @@ -802,7 +802,7 @@
           }
         }
     
    -    FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
    +    FT_TRACE3(( "numGlyphs: %hu\n", maxProfile->numGlyphs ));
     
       Exit:
         return error;
    @@ -1265,11 +1265,11 @@
           }
         }
     
    -    FT_TRACE3(( "sTypoAscender:  %4d\n",   os2->sTypoAscender ));
    -    FT_TRACE3(( "sTypoDescender: %4d\n",   os2->sTypoDescender ));
    -    FT_TRACE3(( "usWinAscent:    %4u\n",   os2->usWinAscent ));
    -    FT_TRACE3(( "usWinDescent:   %4u\n",   os2->usWinDescent ));
    -    FT_TRACE3(( "fsSelection:    0x%2x\n", os2->fsSelection ));
    +    FT_TRACE3(( "sTypoAscender:  %4hd\n",   os2->sTypoAscender ));
    +    FT_TRACE3(( "sTypoDescender: %4hd\n",   os2->sTypoDescender ));
    +    FT_TRACE3(( "usWinAscent:    %4hu\n",   os2->usWinAscent ));
    +    FT_TRACE3(( "usWinDescent:   %4hu\n",   os2->usWinDescent ));
    +    FT_TRACE3(( "fsSelection:    0x%2hx\n", os2->fsSelection ));
     
       Exit:
         return error;
    @@ -1468,7 +1468,7 @@
           gasp_ranges[j].maxPPEM  = FT_GET_USHORT();
           gasp_ranges[j].gaspFlag = FT_GET_USHORT();
     
    -      FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
    +      FT_TRACE3(( "gaspRange %hu: rangeMaxPPEM %5hu, rangeGaspBehavior 0x%hx\n",
                       j,
                       gasp_ranges[j].maxPPEM,
                       gasp_ranges[j].gaspFlag ));
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -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-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Load the metrics tables common to TTF and OTF fonts (body).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -306,7 +306,7 @@
         }
     
     #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    -    if ( var )
    +    if ( var && face->blend )
         {
           FT_Face  f = FT_FACE( face );
           FT_Int   a = (FT_Int)*aadvance;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Load the metrics tables common to TTF and OTF fonts (specification).
      *
    - * Copyright (C) 2006-2022 by
    + * Copyright (C) 2006-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   PostScript name table processing for TrueType and OpenType fonts
      *   (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -58,7 +58,7 @@
     #define MAC_NAME( x )  (FT_String*)psnames->macintosh_name( (FT_UInt)(x) )
     
     
    -#else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
    +#else /* !FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
     
     
        /* Otherwise, we ignore the `psnames' module, and provide our own  */
    @@ -152,7 +152,7 @@
       };
     
     
    -#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
    +#endif /* !FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
     
     
       static FT_Error
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.h	2023-10-06 05:33:33.000000000 +0000
    @@ -5,7 +5,7 @@
      *   PostScript name table processing for TrueType and OpenType fonts
      *   (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType and OpenType embedded bitmap support (body).
      *
    - * Copyright (C) 2005-2022 by
    + * Copyright (C) 2005-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * Copyright 2013 by Google, Inc.
    @@ -385,11 +385,9 @@
     
             /* set the scale values (in 16.16 units) so advances */
             /* from the hmtx and vmtx table are scaled correctly */
    -        metrics->x_scale = FT_MulDiv( metrics->x_ppem,
    -                                      64 * 0x10000,
    +        metrics->x_scale = FT_DivFix( metrics->x_ppem * 64,
                                           face->header.Units_Per_EM );
    -        metrics->y_scale = FT_MulDiv( metrics->y_ppem,
    -                                      64 * 0x10000,
    +        metrics->y_scale = FT_DivFix( metrics->y_ppem * 64,
                                           face->header.Units_Per_EM );
     
             return FT_Err_Ok;
    @@ -399,9 +397,9 @@
           {
             FT_Stream       stream = face->root.stream;
             FT_UInt         offset;
    -        FT_UShort       upem, ppem, resolution;
    +        FT_UShort       ppem, resolution;
             TT_HoriHeader  *hori;
    -        FT_Pos          ppem_; /* to reduce casts */
    +        FT_Fixed        scale;
     
             FT_Error  error;
             FT_Byte*  p;
    @@ -424,32 +422,23 @@
     
             FT_FRAME_EXIT();
     
    -        upem = face->header.Units_Per_EM;
    -        hori = &face->horizontal;
    -
             metrics->x_ppem = ppem;
             metrics->y_ppem = ppem;
     
    -        ppem_ = (FT_Pos)ppem;
    +        scale = FT_DivFix( ppem * 64, face->header.Units_Per_EM );
    +        hori  = &face->horizontal;
     
    -        metrics->ascender =
    -          FT_MulDiv( hori->Ascender, ppem_ * 64, upem );
    -        metrics->descender =
    -          FT_MulDiv( hori->Descender, ppem_ * 64, upem );
    -        metrics->height =
    -          FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap,
    -                     ppem_ * 64, upem );
    -        metrics->max_advance =
    -          FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem );
    +        metrics->ascender    = FT_MulFix( hori->Ascender, scale );
    +        metrics->descender   = FT_MulFix( hori->Descender, scale );
    +        metrics->height      =
    +          FT_MulFix( hori->Ascender - hori->Descender + hori->Line_Gap,
    +                     scale );
    +        metrics->max_advance = FT_MulFix( hori->advance_Width_Max, scale );
     
             /* set the scale values (in 16.16 units) so advances */
             /* from the hmtx and vmtx table are scaled correctly */
    -        metrics->x_scale = FT_MulDiv( metrics->x_ppem,
    -                                      64 * 0x10000,
    -                                      face->header.Units_Per_EM );
    -        metrics->y_scale = FT_MulDiv( metrics->y_ppem,
    -                                      64 * 0x10000,
    -                                      face->header.Units_Per_EM );
    +        metrics->x_scale = scale;
    +        metrics->y_scale = scale;
     
             return error;
           }
    @@ -1204,7 +1193,7 @@
               goto Fail;
     
             p += 1;  /* skip padding */
    -        /* fall-through */
    +        FALL_THROUGH;
     
           case 9:
             loader = tt_sbit_decoder_load_compound;
    @@ -1604,7 +1593,7 @@
         return error;
       }
     
    -  FT_LOCAL( FT_Error )
    +  FT_LOCAL_DEF( FT_Error )
       tt_face_load_sbit_image( TT_Face              face,
                                FT_ULong             strike_index,
                                FT_UInt              glyph_index,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType and OpenType embedded bitmap support (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   WOFF2 Font table tags (base).
      *
    - * Copyright (C) 2019-2022 by
    + * Copyright (C) 2019-2023 by
      * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   WOFF2 Font table tags (specification).
      *
    - * Copyright (C) 2019-2022 by
    + * Copyright (C) 2019-2023 by
      * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   A new `perfect' anti-aliasing renderer (body).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -418,21 +418,21 @@
     
       /* It is faster to write small spans byte-by-byte than calling     */
       /* `memset'.  This is mainly due to the cost of the function call. */
    -#define FT_GRAY_SET( d, s, count )                          \
    -  FT_BEGIN_STMNT                                            \
    -    unsigned char* q = d;                                   \
    -    switch ( count )                                        \
    -    {                                                       \
    -      case 7: *q++ = (unsigned char)s; /* fall through */   \
    -      case 6: *q++ = (unsigned char)s; /* fall through */   \
    -      case 5: *q++ = (unsigned char)s; /* fall through */   \
    -      case 4: *q++ = (unsigned char)s; /* fall through */   \
    -      case 3: *q++ = (unsigned char)s; /* fall through */   \
    -      case 2: *q++ = (unsigned char)s; /* fall through */   \
    -      case 1: *q   = (unsigned char)s; /* fall through */   \
    -      case 0: break;                                        \
    -      default: FT_MEM_SET( d, s, count );                   \
    -    }                                                       \
    +#define FT_GRAY_SET( d, s, count )                   \
    +  FT_BEGIN_STMNT                                     \
    +    unsigned char* q = d;                            \
    +    switch ( count )                                 \
    +    {                                                \
    +      case 7: *q++ = (unsigned char)s; FALL_THROUGH; \
    +      case 6: *q++ = (unsigned char)s; FALL_THROUGH; \
    +      case 5: *q++ = (unsigned char)s; FALL_THROUGH; \
    +      case 4: *q++ = (unsigned char)s; FALL_THROUGH; \
    +      case 3: *q++ = (unsigned char)s; FALL_THROUGH; \
    +      case 2: *q++ = (unsigned char)s; FALL_THROUGH; \
    +      case 1: *q   = (unsigned char)s; FALL_THROUGH; \
    +      case 0: break;                                 \
    +      default: FT_MEM_SET( d, s, count );            \
    +    }                                                \
       FT_END_STMNT
     
     
    @@ -1909,10 +1909,10 @@
     
     
       static int
    -  gray_convert_glyph_inner( RAS_ARG,
    +  gray_convert_glyph_inner( RAS_ARG_
                                 int  continued )
       {
    -    int  error;
    +    volatile int  error;
     
     
         if ( ft_setjmp( ras.jump_buffer ) == 0 )
    @@ -2004,7 +2004,7 @@
             ras.max_ey    = band[0];
             ras.count_ey  = width;
     
    -        error     = gray_convert_glyph_inner( RAS_VAR, continued );
    +        error     = gray_convert_glyph_inner( RAS_VAR_ continued );
             continued = 1;
     
             if ( !error )
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   FreeType smooth renderer declaration
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftsmerrs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   smooth renderer error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Anti-aliasing renderer interface (body).
      *
    - * Copyright (C) 2000-2022 by
    + * Copyright (C) 2000-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Anti-aliasing renderer interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType font driver implementation (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -507,19 +507,34 @@
       FT_DEFINE_SERVICE_MULTIMASTERSREC(
         tt_service_gx_multi_masters,
     
    -    (FT_Get_MM_Func)             NULL,                  /* get_mm              */
    -    (FT_Set_MM_Design_Func)      NULL,                  /* set_mm_design       */
    -    (FT_Set_MM_Blend_Func)       TT_Set_MM_Blend,       /* set_mm_blend        */
    -    (FT_Get_MM_Blend_Func)       TT_Get_MM_Blend,       /* get_mm_blend        */
    -    (FT_Get_MM_Var_Func)         TT_Get_MM_Var,         /* get_mm_var          */
    -    (FT_Set_Var_Design_Func)     TT_Set_Var_Design,     /* set_var_design      */
    -    (FT_Get_Var_Design_Func)     TT_Get_Var_Design,     /* get_var_design      */
    -    (FT_Set_Instance_Func)       TT_Set_Named_Instance, /* set_instance        */
    -    (FT_Set_MM_WeightVector_Func)NULL,                  /* set_mm_weightvector */
    -    (FT_Get_MM_WeightVector_Func)NULL,                  /* get_mm_weightvector */
    -
    -    (FT_Get_Var_Blend_Func)      tt_get_var_blend,      /* get_var_blend       */
    -    (FT_Done_Blend_Func)         tt_done_blend          /* done_blend          */
    +    (FT_Get_MM_Func)        NULL,                  /* get_mm                    */
    +    (FT_Set_MM_Design_Func) NULL,                  /* set_mm_design             */
    +    (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,       /* set_mm_blend              */
    +    (FT_Get_MM_Blend_Func)  TT_Get_MM_Blend,       /* get_mm_blend              */
    +    (FT_Get_MM_Var_Func)    TT_Get_MM_Var,         /* get_mm_var                */
    +    (FT_Set_Var_Design_Func)TT_Set_Var_Design,     /* set_var_design            */
    +    (FT_Get_Var_Design_Func)TT_Get_Var_Design,     /* get_var_design            */
    +    (FT_Set_Instance_Func)  TT_Set_Named_Instance, /* set_instance              */
    +    (FT_Set_MM_WeightVector_Func)
    +                            NULL,                  /* set_mm_weightvector       */
    +    (FT_Get_MM_WeightVector_Func)
    +                            NULL,                  /* get_mm_weightvector       */
    +    (FT_Var_Load_Delta_Set_Idx_Map_Func)
    +                            tt_var_load_delta_set_index_mapping,
    +                                                   /* load_delta_set_idx_map    */
    +    (FT_Var_Load_Item_Var_Store_Func)
    +                            tt_var_load_item_variation_store,
    +                                                   /* load_item_variation_store */
    +    (FT_Var_Get_Item_Delta_Func)
    +                            tt_var_get_item_delta, /* get_item_delta            */
    +    (FT_Var_Done_Item_Var_Store_Func)
    +                            tt_var_done_item_variation_store,
    +                                                   /* done_item_variation_store */
    +    (FT_Var_Done_Delta_Set_Idx_Map_Func)
    +                            tt_var_done_delta_set_index_map,
    +                                                   /* done_delta_set_index_map  */
    +    (FT_Get_Var_Blend_Func) tt_get_var_blend,      /* get_var_blend             */
    +    (FT_Done_Blend_Func)    tt_done_blend          /* done_blend                */
       )
     
       FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level TrueType driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/tterrors.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType Glyph Loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -737,19 +737,19 @@
     
             if ( subglyph->flags & WE_HAVE_A_SCALE )
               FT_TRACE7(( "      scaling: %f\n",
    -                      subglyph->transform.xx / 65536.0 ));
    +                      (double)subglyph->transform.xx / 65536 ));
             else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
               FT_TRACE7(( "      scaling: x=%f, y=%f\n",
    -                      subglyph->transform.xx / 65536.0,
    -                      subglyph->transform.yy / 65536.0 ));
    +                      (double)subglyph->transform.xx / 65536,
    +                      (double)subglyph->transform.yy / 65536 ));
             else if ( subglyph->flags & WE_HAVE_A_2X2 )
             {
               FT_TRACE7(( "      scaling: xx=%f, yx=%f\n",
    -                      subglyph->transform.xx / 65536.0,
    -                      subglyph->transform.yx / 65536.0 ));
    +                      (double)subglyph->transform.xx / 65536,
    +                      (double)subglyph->transform.yx / 65536 ));
               FT_TRACE7(( "               xy=%f, yy=%f\n",
    -                      subglyph->transform.xy / 65536.0,
    -                      subglyph->transform.yy / 65536.0 ));
    +                      (double)subglyph->transform.xy / 65536,
    +                      (double)subglyph->transform.yy / 65536 ));
             }
     
             subglyph++;
    @@ -801,7 +801,7 @@
                        FT_UInt       start_point,
                        FT_UInt       start_contour )
       {
    -    zone->n_points    = (FT_UShort)load->outline.n_points -
    +    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;
    @@ -970,11 +970,6 @@
         outline->points[n_points + 2] = loader->pp3;
         outline->points[n_points + 3] = loader->pp4;
     
    -    outline->tags[n_points    ] = 0;
    -    outline->tags[n_points + 1] = 0;
    -    outline->tags[n_points + 2] = 0;
    -    outline->tags[n_points + 3] = 0;
    -
         n_points += 4;
     
     #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    @@ -985,24 +980,9 @@
             goto Exit;
     
           /* Deltas apply to the unscaled data. */
    -      error = TT_Vary_Apply_Glyph_Deltas( loader->face,
    -                                          loader->glyph_index,
    +      error = TT_Vary_Apply_Glyph_Deltas( loader,
                                               outline,
    -                                          unrounded,
    -                                          (FT_UInt)n_points );
    -
    -      /* recalculate linear horizontal and vertical advances */
    -      /* if we don't have HVAR and VVAR, respectively        */
    -
    -      /* XXX: change all FreeType modules to store `linear' and `vadvance' */
    -      /*      in 26.6 format before the `base' module scales them to 16.16 */
    -      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
    -        loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x -
    -                                       unrounded[n_points - 4].x ) / 64;
    -      if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
    -        loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x -
    -                                         unrounded[n_points - 2].x ) / 64;
    -
    +                                          unrounded );
           if ( error )
             goto Exit;
         }
    @@ -1014,7 +994,7 @@
           tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
     
           FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
    -                     loader->zone.n_points + 4 );
    +                     loader->zone.n_points );
         }
     
         {
    @@ -1156,11 +1136,7 @@
         }
     
         if ( IS_HINTED( loader->load_flags ) )
    -    {
    -      loader->zone.n_points += 4;
    -
           error = TT_Hint_Glyph( loader, 0 );
    -    }
     
     #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       Exit:
    @@ -1373,11 +1349,6 @@
         outline->points[outline->n_points + 2] = loader->pp3;
         outline->points[outline->n_points + 3] = loader->pp4;
     
    -    outline->tags[outline->n_points    ] = 0;
    -    outline->tags[outline->n_points + 1] = 0;
    -    outline->tags[outline->n_points + 2] = 0;
    -    outline->tags[outline->n_points + 3] = 0;
    -
     #ifdef TT_USE_BYTECODE_INTERPRETER
     
         {
    @@ -1436,11 +1407,9 @@
     
         /* Some points are likely touched during execution of  */
         /* instructions on components.  So let's untouch them. */
    -    for ( i = 0; i < loader->zone.n_points; i++ )
    +    for ( i = 0; i < loader->zone.n_points - 4U; i++ )
           loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
     
    -    loader->zone.n_points += 4;
    -
         return TT_Hint_Glyph( loader, 1 );
       }
     
    @@ -1761,57 +1730,29 @@
             /* a small outline structure with four elements for */
             /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
             FT_Vector   points[4];
    -        char        tags[4]     = { 1, 1, 1, 1 };
    -        short       contours[4] = { 0, 1, 2, 3 };
             FT_Outline  outline;
     
             /* unrounded values */
             FT_Vector  unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
     
     
    -        points[0].x = loader->pp1.x;
    -        points[0].y = loader->pp1.y;
    -        points[1].x = loader->pp2.x;
    -        points[1].y = loader->pp2.y;
    -
    -        points[2].x = loader->pp3.x;
    -        points[2].y = loader->pp3.y;
    -        points[3].x = loader->pp4.x;
    -        points[3].y = loader->pp4.y;
    +        points[0] = loader->pp1;
    +        points[1] = loader->pp2;
    +        points[2] = loader->pp3;
    +        points[3] = loader->pp4;
     
    -        outline.n_points   = 4;
    -        outline.n_contours = 4;
    +        outline.n_points   = 0;
    +        outline.n_contours = 0;
             outline.points     = points;
    -        outline.tags       = tags;
    -        outline.contours   = contours;
    +        outline.tags       = NULL;
    +        outline.contours   = NULL;
     
             /* this must be done before scaling */
    -        error = TT_Vary_Apply_Glyph_Deltas( loader->face,
    -                                            glyph_index,
    +        error = TT_Vary_Apply_Glyph_Deltas( loader,
                                                 &outline,
    -                                            unrounded,
    -                                            (FT_UInt)outline.n_points );
    +                                            unrounded );
             if ( error )
               goto Exit;
    -
    -        loader->pp1.x = points[0].x;
    -        loader->pp1.y = points[0].y;
    -        loader->pp2.x = points[1].x;
    -        loader->pp2.y = points[1].y;
    -
    -        loader->pp3.x = points[2].x;
    -        loader->pp3.y = points[2].y;
    -        loader->pp4.x = points[3].x;
    -        loader->pp4.y = points[3].y;
    -
    -        /* recalculate linear horizontal and vertical advances */
    -        /* if we don't have HVAR and VVAR, respectively        */
    -        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
    -          loader->linear = FT_PIX_ROUND( unrounded[1].x -
    -                                         unrounded[0].x ) / 64;
    -        if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
    -          loader->vadvance = FT_PIX_ROUND( unrounded[3].x -
    -                                           unrounded[2].x ) / 64;
           }
     
     #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
    @@ -1959,17 +1900,16 @@
     
             /* construct an outline structure for              */
             /* communication with `TT_Vary_Apply_Glyph_Deltas' */
    -        outline.n_points   = (short)( gloader->current.num_subglyphs + 4 );
    -        outline.n_contours = outline.n_points;
    +        outline.n_contours = outline.n_points = limit;
     
             outline.points   = NULL;
             outline.tags     = NULL;
             outline.contours = NULL;
     
    -        if ( FT_NEW_ARRAY( points, outline.n_points )    ||
    -             FT_NEW_ARRAY( tags, outline.n_points )      ||
    -             FT_NEW_ARRAY( contours, outline.n_points )  ||
    -             FT_NEW_ARRAY( unrounded, outline.n_points ) )
    +        if ( FT_NEW_ARRAY( points, limit + 4 )    ||
    +             FT_NEW_ARRAY( tags, limit + 4 )      ||
    +             FT_NEW_ARRAY( contours, limit + 4 )  ||
    +             FT_NEW_ARRAY( unrounded, limit + 4 ) )
               goto Exit1;
     
             subglyph = gloader->current.subglyphs;
    @@ -1985,28 +1925,10 @@
               contours[i] = i;
             }
     
    -        points[i].x = loader->pp1.x;
    -        points[i].y = loader->pp1.y;
    -        tags[i]     = 1;
    -        contours[i] = i;
    -
    -        i++;
    -        points[i].x = loader->pp2.x;
    -        points[i].y = loader->pp2.y;
    -        tags[i]     = 1;
    -        contours[i] = i;
    -
    -        i++;
    -        points[i].x = loader->pp3.x;
    -        points[i].y = loader->pp3.y;
    -        tags[i]     = 1;
    -        contours[i] = i;
    -
    -        i++;
    -        points[i].x = loader->pp4.x;
    -        points[i].y = loader->pp4.y;
    -        tags[i]     = 1;
    -        contours[i] = i;
    +        points[i++] = loader->pp1;
    +        points[i++] = loader->pp2;
    +        points[i++] = loader->pp3;
    +        points[i  ] = loader->pp4;
     
             outline.points   = points;
             outline.tags     = tags;
    @@ -2014,12 +1936,9 @@
     
             /* this call provides additional offsets */
             /* for each component's translation      */
    -        if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
    -                             face,
    -                             glyph_index,
    -                             &outline,
    -                             unrounded,
    -                             (FT_UInt)outline.n_points ) ) )
    +        if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( loader,
    +                                                       &outline,
    +                                                       unrounded ) ) )
               goto Exit1;
     
             subglyph = gloader->current.subglyphs;
    @@ -2033,27 +1952,6 @@
               }
             }
     
    -        loader->pp1.x = points[i + 0].x;
    -        loader->pp1.y = points[i + 0].y;
    -        loader->pp2.x = points[i + 1].x;
    -        loader->pp2.y = points[i + 1].y;
    -
    -        loader->pp3.x = points[i + 2].x;
    -        loader->pp3.y = points[i + 2].y;
    -        loader->pp4.x = points[i + 3].x;
    -        loader->pp4.y = points[i + 3].y;
    -
    -        /* recalculate linear horizontal and vertical advances */
    -        /* if we don't have HVAR and VVAR, respectively        */
    -        if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
    -          loader->linear =
    -            FT_PIX_ROUND( unrounded[outline.n_points - 3].x -
    -                          unrounded[outline.n_points - 4].x ) / 64;
    -        if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
    -          loader->vadvance =
    -            FT_PIX_ROUND( unrounded[outline.n_points - 1].x -
    -                          unrounded[outline.n_points - 2].x ) / 64;
    -
           Exit1:
             FT_FREE( outline.points );
             FT_FREE( outline.tags );
    @@ -2229,12 +2127,11 @@
       compute_glyph_metrics( TT_Loader  loader,
                              FT_UInt    glyph_index )
       {
    -    TT_Face    face   = loader->face;
    -
    +    TT_Face       face  = loader->face;
    +    TT_Size       size  = loader->size;
    +    TT_GlyphSlot  glyph = loader->glyph;
         FT_BBox       bbox;
         FT_Fixed      y_scale;
    -    TT_GlyphSlot  glyph = loader->glyph;
    -    TT_Size       size  = loader->size;
     
     
         y_scale = 0x10000L;
    @@ -2372,17 +2269,13 @@
                        FT_UInt       glyph_index,
                        FT_Int32      load_flags )
       {
    -    TT_Face             face;
    -    SFNT_Service        sfnt;
    -    FT_Stream           stream;
    +    TT_Face             face   = (TT_Face)glyph->face;
    +    SFNT_Service        sfnt   = (SFNT_Service)face->sfnt;
    +    FT_Stream           stream = face->root.stream;
         FT_Error            error;
         TT_SBit_MetricsRec  sbit_metrics;
     
     
    -    face   = (TT_Face)glyph->face;
    -    sfnt   = (SFNT_Service)face->sfnt;
    -    stream = face->root.stream;
    -
         error = sfnt->load_sbit_image( face,
                                        size->strike_index,
                                        glyph_index,
    @@ -2433,22 +2326,19 @@
                       FT_Int32      load_flags,
                       FT_Bool       glyf_table_only )
       {
    -    TT_Face    face;
    -    FT_Stream  stream;
    +    TT_Face    face   = (TT_Face)glyph->face;
    +    FT_Stream  stream = face->root.stream;
     
     #ifdef TT_USE_BYTECODE_INTERPRETER
         FT_Error   error;
         FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
     #if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
         defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
    -    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face );
    +    TT_Driver  driver   = (TT_Driver)FT_FACE_DRIVER( glyph->face );
     #endif
     #endif
     
     
    -    face   = (TT_Face)glyph->face;
    -    stream = face->root.stream;
    -
         FT_ZERO( loader );
     
     #ifdef TT_USE_BYTECODE_INTERPRETER
    @@ -2816,6 +2706,7 @@
                      FT_UInt       glyph_index,
                      FT_Int32      load_flags )
       {
    +    TT_Face       face = (TT_Face)glyph->face;
         FT_Error      error;
         TT_LoaderRec  loader;
     
    @@ -2840,8 +2731,6 @@
             /* if we have a bitmap-only font, return an empty glyph            */
             if ( !FT_IS_SCALABLE( glyph->face ) )
             {
    -          TT_Face  face = (TT_Face)glyph->face;
    -
               FT_Short  left_bearing = 0;
               FT_Short  top_bearing  = 0;
     
    @@ -2900,9 +2789,6 @@
             if ( FT_IS_SCALABLE( glyph->face ) ||
                  FT_HAS_SBIX( glyph->face )    )
             {
    -          TT_Face  face = (TT_Face)glyph->face;
    -
    -
               /* for the bbox we need the header only */
               (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
               (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
    @@ -2971,23 +2857,23 @@
     #ifdef FT_CONFIG_OPTION_SVG
     
         /* check for OT-SVG */
    -    if ( ( load_flags & FT_LOAD_COLOR ) && ( (TT_Face)glyph->face )->svg )
    +    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
         {
    -      SFNT_Service  sfnt;
    -
    -      FT_Short   leftBearing;
    -      FT_Short   topBearing;
    -      FT_UShort  advanceX;
    -      FT_UShort  advanceY;
    +      SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
     
     
           FT_TRACE3(( "Trying to load SVG glyph\n" ));
    -      sfnt = (SFNT_Service)( (TT_Face)glyph->face )->sfnt;
     
           error = sfnt->load_svg_doc( glyph, glyph_index );
           if ( !error )
           {
    -        TT_Face  face = (TT_Face)glyph->face;
    +        FT_Fixed  x_scale = size->root.metrics.x_scale;
    +        FT_Fixed  y_scale = size->root.metrics.y_scale;
    +
    +        FT_Short   leftBearing;
    +        FT_Short   topBearing;
    +        FT_UShort  advanceX;
    +        FT_UShort  advanceY;
     
     
             FT_TRACE3(( "Successfully loaded SVG glyph\n" ));
    @@ -3005,15 +2891,11 @@
                                &topBearing,
                                &advanceY );
     
    -        advanceX = (FT_UShort)FT_MulDiv( advanceX,
    -                                         glyph->face->size->metrics.x_ppem,
    -                                         glyph->face->units_per_EM );
    -        advanceY = (FT_UShort)FT_MulDiv( advanceY,
    -                                         glyph->face->size->metrics.y_ppem,
    -                                         glyph->face->units_per_EM );
    +        glyph->linearHoriAdvance = advanceX;
    +        glyph->linearVertAdvance = advanceY;
     
    -        glyph->metrics.horiAdvance = advanceX << 6;
    -        glyph->metrics.vertAdvance = advanceY << 6;
    +        glyph->metrics.horiAdvance = FT_MulFix( advanceX, x_scale );
    +        glyph->metrics.vertAdvance = FT_MulFix( advanceY, y_scale );
     
             return error;
           }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType Glyph Loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType GX Font Variation loader
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -42,6 +42,7 @@
     #include 
     #include 
     #include FT_CONFIG_CONFIG_H
    +#include 
     #include 
     #include 
     #include 
    @@ -353,15 +354,24 @@
       static void
       ft_var_load_avar( TT_Face  face )
       {
    -    FT_Stream       stream = FT_FACE_STREAM( face );
    -    FT_Memory       memory = stream->memory;
    +    FT_Error   error;
    +    FT_Stream  stream = FT_FACE_STREAM( face );
    +    FT_Memory  memory = stream->memory;
    +    FT_Int     i, j;
    +
         GX_Blend        blend  = face->blend;
         GX_AVarSegment  segment;
    -    FT_Error        error;
    -    FT_Long         version;
    -    FT_Long         axisCount;
    -    FT_Int          i, j;
    -    FT_ULong        table_len;
    +    GX_AVarTable    table;
    +
    +    FT_Long   version;
    +    FT_Long   axisCount;
    +    FT_ULong  table_len;
    +
    +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
    +    FT_ULong  table_offset;
    +    FT_ULong  store_offset;
    +    FT_ULong  axisMap_offset;
    +#endif
     
     
         FT_TRACE2(( "AVAR " ));
    @@ -374,13 +384,21 @@
           return;
         }
     
    +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
    +    table_offset = FT_STREAM_POS();
    +#endif
    +
         if ( FT_FRAME_ENTER( table_len ) )
           return;
     
         version   = FT_GET_LONG();
         axisCount = FT_GET_LONG();
     
    -    if ( version != 0x00010000L )
    +    if ( version != 0x00010000L
    +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
    +         && version != 0x00020000L
    +#endif
    +       )
         {
           FT_TRACE2(( "bad table version\n" ));
           goto Exit;
    @@ -396,10 +414,14 @@
           goto Exit;
         }
     
    -    if ( FT_QNEW_ARRAY( blend->avar_segment, axisCount ) )
    +    if ( FT_NEW( blend->avar_table ) )
           goto Exit;
    +    table = blend->avar_table;
     
    -    segment = &blend->avar_segment[0];
    +    if ( FT_QNEW_ARRAY( table->avar_segment, axisCount ) )
    +      goto Exit;
    +
    +    segment = &table->avar_segment[0];
         for ( i = 0; i < axisCount; i++, segment++ )
         {
           FT_TRACE5(( "  axis %d:\n", i ));
    @@ -412,9 +434,9 @@
             /* it right now since loading the `avar' table is optional.   */
     
             for ( j = i - 1; j >= 0; j-- )
    -          FT_FREE( blend->avar_segment[j].correspondence );
    +          FT_FREE( table->avar_segment[j].correspondence );
     
    -        FT_FREE( blend->avar_segment );
    +        FT_FREE( table->avar_segment );
             goto Exit;
           }
     
    @@ -426,20 +448,51 @@
               FT_fdot14ToFixed( FT_GET_SHORT() );
     
             FT_TRACE5(( "    mapping %.5f to %.5f\n",
    -                    segment->correspondence[j].fromCoord / 65536.0,
    -                    segment->correspondence[j].toCoord / 65536.0 ));
    +                    (double)segment->correspondence[j].fromCoord / 65536,
    +                    (double)segment->correspondence[j].toCoord / 65536 ));
           }
     
           FT_TRACE5(( "\n" ));
         }
     
    +#ifndef TT_CONFIG_OPTION_NO_BORING_EXPANSION
    +    if ( version < 0x00020000L )
    +      goto Exit;
    +
    +    axisMap_offset = FT_GET_ULONG();
    +    store_offset   = FT_GET_ULONG();
    +
    +    if ( store_offset )
    +    {
    +      error = tt_var_load_item_variation_store(
    +                face,
    +                table_offset + store_offset,
    +                &table->itemStore );
    +      if ( error )
    +        goto Exit;
    +    }
    +
    +    if ( axisMap_offset )
    +    {
    +      error = tt_var_load_delta_set_index_mapping(
    +                face,
    +                table_offset + axisMap_offset,
    +                &table->axisMap,
    +                &table->itemStore,
    +                table_len );
    +      if ( error )
    +        goto Exit;
    +    }
    +#endif
    +
    +
       Exit:
         FT_FRAME_EXIT();
       }
     
     
    -  static FT_Error
    -  ft_var_load_item_variation_store( TT_Face          face,
    +  FT_LOCAL_DEF( FT_Error )
    +  tt_var_load_item_variation_store( TT_Face          face,
                                         FT_ULong         offset,
                                         GX_ItemVarStore  itemStore )
       {
    @@ -449,13 +502,15 @@
         FT_Error   error;
         FT_UShort  format;
         FT_ULong   region_offset;
    -    FT_UInt    i, j, k;
    -    FT_UInt    wordDeltaCount;
    -    FT_Bool    long_words;
     
    -    GX_Blend        blend = face->blend;
    -    GX_ItemVarData  varData;
    +    FT_UInt    data_count;
    +    FT_UShort  axis_count;
    +    FT_UInt    region_count;
    +
    +    FT_UInt  i, j, k;
    +    FT_Bool  long_words;
     
    +    GX_Blend   blend           = face->blend;
         FT_ULong*  dataOffsetArray = NULL;
     
     
    @@ -465,31 +520,31 @@
     
         if ( format != 1 )
         {
    -      FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n",
    +      FT_TRACE2(( "tt_var_load_item_variation_store: bad store format %d\n",
                       format ));
           error = FT_THROW( Invalid_Table );
           goto Exit;
         }
     
         /* read top level fields */
    -    if ( FT_READ_ULONG( region_offset )         ||
    -         FT_READ_USHORT( itemStore->dataCount ) )
    +    if ( FT_READ_ULONG( region_offset ) ||
    +         FT_READ_USHORT( data_count )   )
           goto Exit;
     
         /* we need at least one entry in `itemStore->varData' */
    -    if ( !itemStore->dataCount )
    +    if ( !data_count )
         {
    -      FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" ));
    +      FT_TRACE2(( "tt_var_load_item_variation_store: missing varData\n" ));
           error = FT_THROW( Invalid_Table );
           goto Exit;
         }
     
         /* make temporary copy of item variation data offsets; */
         /* we will parse region list first, then come back     */
    -    if ( FT_QNEW_ARRAY( dataOffsetArray, itemStore->dataCount ) )
    +    if ( FT_QNEW_ARRAY( dataOffsetArray, data_count ) )
           goto Exit;
     
    -    for ( i = 0; i < itemStore->dataCount; i++ )
    +    for ( i = 0; i < data_count; i++ )
         {
           if ( FT_READ_ULONG( dataOffsetArray[i] ) )
             goto Exit;
    @@ -499,39 +554,40 @@
         if ( FT_STREAM_SEEK( offset + region_offset ) )
           goto Exit;
     
    -    if ( FT_READ_USHORT( itemStore->axisCount )   ||
    -         FT_READ_USHORT( itemStore->regionCount ) )
    +    if ( FT_READ_USHORT( axis_count )   ||
    +         FT_READ_USHORT( region_count ) )
           goto Exit;
     
    -    if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis )
    +    if ( axis_count != (FT_Long)blend->mmvar->num_axis )
         {
    -      FT_TRACE2(( "ft_var_load_item_variation_store:"
    +      FT_TRACE2(( "tt_var_load_item_variation_store:"
                       " number of axes in item variation store\n" ));
           FT_TRACE2(( "                                 "
                       " and `fvar' table are different\n" ));
           error = FT_THROW( Invalid_Table );
           goto Exit;
         }
    +    itemStore->axisCount = axis_count;
     
         /* new constraint in OpenType 1.8.4 */
    -    if ( itemStore->regionCount >= 32768U )
    +    if ( region_count >= 32768U )
         {
    -      FT_TRACE2(( "ft_var_load_item_variation_store:"
    +      FT_TRACE2(( "tt_var_load_item_variation_store:"
                       " too many variation region tables\n" ));
           error = FT_THROW( Invalid_Table );
           goto Exit;
         }
     
    -    if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) )
    +    if ( FT_NEW_ARRAY( itemStore->varRegionList, region_count ) )
           goto Exit;
    +    itemStore->regionCount = region_count;
     
         for ( i = 0; i < itemStore->regionCount; i++ )
         {
           GX_AxisCoords  axisCoords;
     
     
    -      if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList,
    -                         itemStore->axisCount ) )
    +      if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, axis_count ) )
             goto Exit;
     
           axisCoords = itemStore->varRegionList[i].axisList;
    @@ -555,47 +611,53 @@
         /* end of region list parse */
     
         /* use dataOffsetArray now to parse varData items */
    -    if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) )
    +    if ( FT_NEW_ARRAY( itemStore->varData, data_count ) )
           goto Exit;
    +    itemStore->dataCount = data_count;
     
    -    for ( i = 0; i < itemStore->dataCount; i++ )
    +    for ( i = 0; i < data_count; i++ )
         {
    -      varData = &itemStore->varData[i];
    +      GX_ItemVarData  varData = &itemStore->varData[i];
    +
    +      FT_UInt  item_count;
    +      FT_UInt  word_delta_count;
    +      FT_UInt  region_idx_count;
    +
     
           if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
             goto Exit;
     
    -      if ( FT_READ_USHORT( varData->itemCount )      ||
    -           FT_READ_USHORT( wordDeltaCount )          ||
    -           FT_READ_USHORT( varData->regionIdxCount ) )
    +      if ( FT_READ_USHORT( item_count )       ||
    +           FT_READ_USHORT( word_delta_count ) ||
    +           FT_READ_USHORT( region_idx_count ) )
             goto Exit;
     
    -      long_words      = !!( wordDeltaCount & 0x8000 );
    -      wordDeltaCount &= 0x7FFF;
    +      long_words        = !!( word_delta_count & 0x8000 );
    +      word_delta_count &= 0x7FFF;
     
           /* check some data consistency */
    -      if ( wordDeltaCount > varData->regionIdxCount )
    +      if ( word_delta_count > region_idx_count )
           {
             FT_TRACE2(( "bad short count %d or region count %d\n",
    -                    wordDeltaCount,
    -                    varData->regionIdxCount ));
    +                    word_delta_count,
    +                    region_idx_count ));
             error = FT_THROW( Invalid_Table );
             goto Exit;
           }
     
    -      if ( varData->regionIdxCount > itemStore->regionCount )
    +      if ( region_idx_count > itemStore->regionCount )
           {
             FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n",
    -                    varData->regionIdxCount,
    +                    region_idx_count,
                         i ));
             error = FT_THROW( Invalid_Table );
             goto Exit;
           }
     
           /* parse region indices */
    -      if ( FT_NEW_ARRAY( varData->regionIndices,
    -                         varData->regionIdxCount ) )
    +      if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) )
             goto Exit;
    +      varData->regionIdxCount = region_idx_count;
     
           for ( j = 0; j < varData->regionIdxCount; j++ )
           {
    @@ -611,54 +673,35 @@
             }
           }
     
    -      /* Parse delta set.                                                */
    -      /*                                                                 */
    -      /* On input, deltas are (wordDeltaCount + regionIdxCount) bytes    */
    -      /* each if `long_words` isn't set, and twice as much otherwise.    */
    -      /*                                                                 */
    -      /* On output, deltas are expanded to `regionIdxCount` shorts each. */
    -      if ( FT_NEW_ARRAY( varData->deltaSet,
    -                         varData->regionIdxCount * varData->itemCount ) )
    +      /* Parse delta set.                                                  */
    +      /*                                                                   */
    +      /* On input, deltas are (word_delta_count + region_idx_count) bytes  */
    +      /* each if `long_words` isn't set, and twice as much otherwise.      */
    +      /*                                                                   */
    +      /* On output, deltas are expanded to `region_idx_count` shorts each. */
    +      if ( FT_NEW_ARRAY( varData->deltaSet, item_count * region_idx_count ) )
             goto Exit;
    +      varData->itemCount = item_count;
     
    -      /* the delta set is stored as a 2-dimensional array of shorts */
    -      if ( long_words )
    -      {
    -        /* new in OpenType 1.9, currently for 'COLR' table only;          */
    -        /* the deltas are interpreted as 16.16 fixed-point scaling values */
    -
    -        /* not supported yet */
    -
    -        error = FT_THROW( Invalid_Table );
    -        goto Exit;
    -      }
    -      else
    +      for ( j = 0; j < item_count * region_idx_count; )
           {
    -        for ( j = 0; j < varData->itemCount * varData->regionIdxCount; )
    +        if ( long_words )
             {
    -          for ( k = 0; k < wordDeltaCount; k++, j++ )
    -          {
    -            /* read the short deltas */
    -            FT_Short  delta;
    -
    -
    -            if ( FT_READ_SHORT( delta ) )
    +          for ( k = 0; k < word_delta_count; k++, j++ )
    +            if ( FT_READ_LONG( varData->deltaSet[j] ) )
                   goto Exit;
    -
    -            varData->deltaSet[j] = delta;
    -          }
    -
    -          for ( ; k < varData->regionIdxCount; k++, j++ )
    -          {
    -            /* read the (signed) byte deltas */
    -            FT_Char  delta;
    -
    -
    -            if ( FT_READ_CHAR( delta ) )
    +          for ( ; k < region_idx_count; k++, j++ )
    +            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
    +              goto Exit;
    +        }
    +        else
    +        {
    +          for ( k = 0; k < word_delta_count; k++, j++ )
    +            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
    +              goto Exit;
    +          for ( ; k < region_idx_count; k++, j++ )
    +            if ( FT_READ_CHAR( varData->deltaSet[j] ) )
                   goto Exit;
    -
    -            varData->deltaSet[j] = delta;
    -          }
             }
           }
         }
    @@ -670,8 +713,8 @@
       }
     
     
    -  static FT_Error
    -  ft_var_load_delta_set_index_mapping( TT_Face            face,
    +  FT_LOCAL_DEF( FT_Error )
    +  tt_var_load_delta_set_index_mapping( TT_Face            face,
                                            FT_ULong           offset,
                                            GX_DeltaSetIdxMap  map,
                                            GX_ItemVarStore    itemStore,
    @@ -728,7 +771,7 @@
         /* rough sanity check */
         if ( map->mapCount * entrySize > table_len )
         {
    -      FT_TRACE1(( "ft_var_load_delta_set_index_mapping:"
    +      FT_TRACE1(( "tt_var_load_delta_set_index_mapping:"
                       " invalid number of delta-set index mappings\n" ));
           error = FT_THROW( Invalid_Table );
           goto Exit;
    @@ -758,6 +801,16 @@
             mapData = ( mapData << 8 ) | data;
           }
     
    +      /* new in OpenType 1.8.4 */
    +      if ( mapData == 0xFFFFFFFFUL )
    +      {
    +        /* no variation data for this item */
    +        map->outerIndex[i] = 0xFFFFU;
    +        map->innerIndex[i] = 0xFFFFU;
    +
    +        continue;
    +      }
    +
           outerIndex = mapData >> innerBitCount;
     
           if ( outerIndex >= itemStore->dataCount )
    @@ -887,7 +940,7 @@
           table = blend->hvar_table;
         }
     
    -    error = ft_var_load_item_variation_store(
    +    error = tt_var_load_item_variation_store(
                   face,
                   table_offset + store_offset,
                   &table->itemStore );
    @@ -896,7 +949,7 @@
     
         if ( widthMap_offset )
         {
    -      error = ft_var_load_delta_set_index_mapping(
    +      error = tt_var_load_delta_set_index_mapping(
                     face,
                     table_offset + widthMap_offset,
                     &table->widthMap,
    @@ -938,26 +991,47 @@
       }
     
     
    -  static FT_Int
    -  ft_var_get_item_delta( TT_Face          face,
    +  FT_LOCAL_DEF( FT_ItemVarDelta )
    +  tt_var_get_item_delta( TT_Face          face,
                              GX_ItemVarStore  itemStore,
                              FT_UInt          outerIndex,
                              FT_UInt          innerIndex )
       {
    -    GX_ItemVarData  varData;
    -    FT_Short*       deltaSet;
    +    FT_Stream  stream = FT_FACE_STREAM( face );
    +    FT_Memory  memory = stream->memory;
    +    FT_Error   error  = FT_Err_Ok;
    +
    +    GX_ItemVarData    varData;
    +    FT_ItemVarDelta*  deltaSet;
     
    -    FT_UInt   master, j;
    -    FT_Fixed  netAdjustment = 0;     /* accumulated adjustment */
    -    FT_Fixed  scaledDelta;
    -    FT_Fixed  delta;
    +    FT_UInt          master, j;
    +    FT_Fixed*        scalars = NULL;
    +    FT_ItemVarDelta  returnValue;
     
     
    +    if ( !face->blend || !face->blend->normalizedcoords )
    +      return 0;
    +
    +    /* OpenType 1.8.4+: No variation data for this item */
    +    /* as indices have special value 0xFFFF.            */
    +    if ( outerIndex == 0xFFFF && innerIndex == 0xFFFF )
    +      return 0;
    +
         /* See pseudo code from `Font Variations Overview' */
         /* in the OpenType specification.                  */
     
    +    if ( outerIndex >= itemStore->dataCount )
    +      return 0; /* Out of range. */
    +
         varData  = &itemStore->varData[outerIndex];
    -    deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex];
    +    deltaSet = FT_OFFSET( varData->deltaSet,
    +                          varData->regionIdxCount * innerIndex );
    +
    +    if ( innerIndex >= varData->itemCount )
    +      return 0; /* Out of range. */
    +
    +    if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
    +      return 0;
     
         /* outer loop steps through master designs to be blended */
         for ( master = 0; master < varData->regionIdxCount; master++ )
    @@ -1008,18 +1082,33 @@
                 FT_MulDiv( scalar,
                            axis->endCoord - face->blend->normalizedcoords[j],
                            axis->endCoord - axis->peakCoord );
    -      } /* per-axis loop */
     
    -      /* get the scaled delta for this region */
    -      delta       = FT_intToFixed( deltaSet[master] );
    -      scaledDelta = FT_MulFix( scalar, delta );
    +      } /* per-axis loop */
     
    -      /* accumulate the adjustments from each region */
    -      netAdjustment = netAdjustment + scaledDelta;
    +      scalars[master] = scalar;
     
         } /* per-region loop */
     
    -    return FT_fixedToInt( netAdjustment );
    +
    +    /* Compute the scaled delta for this region.
    +     *
    +     * From: https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#item-variation-store-header-and-item-variation-data-subtables:
    +     *
    +     *   `Fixed` is a 32-bit (16.16) type and, in the general case, requires
    +     *   32-bit deltas.  As described above, the `DeltaSet` record can
    +     *   accommodate deltas that are, logically, either 16-bit or 32-bit.
    +     *   When scaled deltas are applied to `Fixed` values, the `Fixed` value
    +     *   is treated like a 32-bit integer.
    +     *
    +     * `FT_MulAddFix` internally uses 64-bit precision; it thus can handle
    +     * deltas ranging from small 8-bit to large 32-bit values that are
    +     * applied to 16.16 `FT_Fixed` / OpenType `Fixed` values.
    +     */
    +    returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
    +
    +    FT_FREE( scalars );
    +
    +    return returnValue;
       }
     
     
    @@ -1112,35 +1201,27 @@
         }
         else
         {
    -      GX_ItemVarData  varData;
    -
    -
           /* no widthMap data */
           outerIndex = 0;
           innerIndex = gindex;
    -
    -      varData = &table->itemStore.varData[outerIndex];
    -      if ( gindex >= varData->itemCount )
    -      {
    -        FT_TRACE2(( "gindex %d out of range\n", gindex ));
    -        error = FT_THROW( Invalid_Argument );
    -        goto Exit;
    -      }
         }
     
    -    delta = ft_var_get_item_delta( face,
    +    delta = tt_var_get_item_delta( face,
                                        &table->itemStore,
                                        outerIndex,
                                        innerIndex );
     
    -    FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n",
    -                vertical ? "vertical height" : "horizontal width",
    -                *avalue,
    -                delta,
    -                delta == 1 ? "" : "s",
    -                vertical ? "VVAR" : "HVAR" ));
    +    if ( delta )
    +    {
    +      FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n",
    +                  vertical ? "vertical height" : "horizontal width",
    +                  *avalue,
    +                  delta,
    +                  delta == 1 ? "" : "s",
    +                  vertical ? "VVAR" : "HVAR" ));
     
    -    *avalue += delta;
    +      *avalue = ADD_INT( *avalue, delta );
    +    }
     
       Exit:
         return error;
    @@ -1307,7 +1388,7 @@
     
         records_offset = FT_STREAM_POS();
     
    -    error = ft_var_load_item_variation_store(
    +    error = tt_var_load_item_variation_store(
                   face,
                   table_offset + store_offset,
                   &blend->mvar_table->itemStore );
    @@ -1323,7 +1404,7 @@
           return;
     
         value     = blend->mvar_table->values;
    -    limit     = value + blend->mvar_table->valueCount;
    +    limit     = FT_OFFSET( value, blend->mvar_table->valueCount );
         itemStore = &blend->mvar_table->itemStore;
     
         for ( ; value < limit; value++ )
    @@ -1332,6 +1413,13 @@
           value->outerIndex = FT_GET_USHORT();
           value->innerIndex = FT_GET_USHORT();
     
    +      /* new in OpenType 1.8.4 */
    +      if ( value->outerIndex == 0xFFFFU && value->innerIndex == 0xFFFFU )
    +      {
    +        /* no variation data for this item */
    +        continue;
    +      }
    +
           if ( value->outerIndex >= itemStore->dataCount                  ||
                value->innerIndex >= itemStore->varData[value->outerIndex]
                                                       .itemCount          )
    @@ -1349,7 +1437,7 @@
         FT_TRACE2(( "loaded\n" ));
     
         value = blend->mvar_table->values;
    -    limit = value + blend->mvar_table->valueCount;
    +    limit = FT_OFFSET( value, blend->mvar_table->valueCount );
     
         /* save original values of the data MVAR is going to modify */
         for ( ; value < limit; value++ )
    @@ -1414,7 +1502,7 @@
           return;
     
         value = blend->mvar_table->values;
    -    limit = value + blend->mvar_table->valueCount;
    +    limit = FT_OFFSET( value, blend->mvar_table->valueCount );
     
         for ( ; value < limit; value++ )
         {
    @@ -1422,12 +1510,12 @@
           FT_Int     delta;
     
     
    -      delta = ft_var_get_item_delta( face,
    +      delta = tt_var_get_item_delta( face,
                                          &blend->mvar_table->itemStore,
                                          value->outerIndex,
                                          value->innerIndex );
     
    -      if ( p )
    +      if ( p && delta )
           {
             FT_TRACE5(( "value %c%c%c%c (%d unit%s) adjusted by %d unit%s (MVAR)\n",
                         (FT_Char)( value->tag >> 24 ),
    @@ -1725,7 +1813,7 @@
               blend->tuplecoords[i * gvar_head.axisCount + j] =
                 FT_fdot14ToFixed( FT_GET_SHORT() );
               FT_TRACE5(( "%.5f ",
    -            blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 ));
    +            (double)blend->tuplecoords[i * gvar_head.axisCount + j] / 65536 ));
             }
             FT_TRACE5(( "]\n" ));
           }
    @@ -1796,7 +1884,7 @@
         for ( i = 0; i < blend->num_axis; i++ )
         {
           FT_TRACE6(( "    axis %d coordinate %.5f:\n",
    -                  i, blend->normalizedcoords[i] / 65536.0 ));
    +                  i, (double)blend->normalizedcoords[i] / 65536 ));
     
           /* It's not clear why (for intermediate tuples) we don't need     */
           /* to check against start/end -- the documentation says we don't. */
    @@ -1819,7 +1907,7 @@
           if ( blend->normalizedcoords[i] == tuple_coords[i] )
           {
             FT_TRACE6(( "      tuple coordinate %.5f fits perfectly\n",
    -                    tuple_coords[i] / 65536.0 ));
    +                    (double)tuple_coords[i] / 65536 ));
             /* `apply' does not change */
             continue;
           }
    @@ -1832,13 +1920,13 @@
                  blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) )
             {
               FT_TRACE6(( "      tuple coordinate %.5f is exceeded, stop\n",
    -                      tuple_coords[i] / 65536.0 ));
    +                      (double)tuple_coords[i] / 65536 ));
               apply = 0;
               break;
             }
     
             FT_TRACE6(( "      tuple coordinate %.5f fits\n",
    -                    tuple_coords[i] / 65536.0 ));
    +                    (double)tuple_coords[i] / 65536 ));
             apply = FT_MulDiv( apply,
                                blend->normalizedcoords[i],
                                tuple_coords[i] );
    @@ -1852,15 +1940,15 @@
             {
               FT_TRACE6(( "      intermediate tuple range ]%.5f;%.5f[ is exceeded,"
                           " stop\n",
    -                      im_start_coords[i] / 65536.0,
    -                      im_end_coords[i] / 65536.0 ));
    +                      (double)im_start_coords[i] / 65536,
    +                      (double)im_end_coords[i] / 65536 ));
               apply = 0;
               break;
             }
     
             FT_TRACE6(( "      intermediate tuple range ]%.5f;%.5f[ fits\n",
    -                    im_start_coords[i] / 65536.0,
    -                    im_end_coords[i] / 65536.0 ));
    +                    (double)im_start_coords[i] / 65536,
    +                    (double)im_end_coords[i] / 65536 ));
             if ( blend->normalizedcoords[i] < tuple_coords[i] )
               apply = FT_MulDiv( apply,
                                  blend->normalizedcoords[i] - im_start_coords[i],
    @@ -1872,7 +1960,7 @@
           }
         }
     
    -    FT_TRACE6(( "    apply factor is %.5f\n", apply / 65536.0 ));
    +    FT_TRACE6(( "    apply factor is %.5f\n", (double)apply / 65536 ));
     
         return apply;
       }
    @@ -1886,12 +1974,18 @@
                             FT_Fixed*  coords,
                             FT_Fixed*  normalized )
       {
    +    FT_Error   error  = FT_Err_Ok;
    +    FT_Memory  memory = face->root.memory;
    +    FT_UInt    i, j;
    +
         GX_Blend        blend;
         FT_MM_Var*      mmvar;
    -    FT_UInt         i, j;
         FT_Var_Axis*    a;
         GX_AVarSegment  av;
     
    +    FT_Fixed*  new_normalized = NULL;
    +    FT_Fixed*  old_normalized;
    +
     
         blend = face->blend;
         mmvar = blend->mmvar;
    @@ -1914,15 +2008,15 @@
           FT_Fixed  coord = coords[i];
     
     
    -      FT_TRACE5(( "    %d: %.5f\n", i, coord / 65536.0 ));
    +      FT_TRACE5(( "    %d: %.5f\n", i, (double)coord / 65536 ));
           if ( coord > a->maximum || coord < a->minimum )
           {
             FT_TRACE1(( "ft_var_to_normalized: design coordinate %.5f\n",
    -                    coord / 65536.0 ));
    +                    (double)coord / 65536 ));
             FT_TRACE1(( "                      is out of range [%.5f;%.5f];"
                         " clamping\n",
    -                    a->minimum / 65536.0,
    -                    a->maximum / 65536.0 ));
    +                    (double)a->minimum / 65536,
    +                    (double)a->maximum / 65536 ));
           }
     
           if ( coord > a->def )
    @@ -1942,30 +2036,91 @@
         for ( ; i < mmvar->num_axis; i++ )
           normalized[i] = 0;
     
    -    if ( blend->avar_segment )
    +    if ( blend->avar_table )
         {
    +      GX_AVarTable  table = blend->avar_table;
    +
    +
           FT_TRACE5(( "normalized design coordinates"
                       " before applying `avar' data:\n" ));
     
    -      av = blend->avar_segment;
    -      for ( i = 0; i < mmvar->num_axis; i++, av++ )
    +      if ( table->avar_segment )
           {
    -        for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
    +        av = table->avar_segment;
    +
    +        for ( i = 0; i < mmvar->num_axis; i++, av++ )
             {
    -          if ( normalized[i] < av->correspondence[j].fromCoord )
    +          for ( j = 1; j < (FT_UInt)av->pairCount; j++ )
               {
    -            FT_TRACE5(( "  %.5f\n", normalized[i] / 65536.0 ));
    +            if ( normalized[i] < av->correspondence[j].fromCoord )
    +            {
    +              FT_TRACE5(( "  %.5f\n", (double)normalized[i] / 65536 ));
    +
    +              normalized[i] =
    +                FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
    +                           av->correspondence[j].toCoord -
    +                             av->correspondence[j - 1].toCoord,
    +                           av->correspondence[j].fromCoord -
    +                             av->correspondence[j - 1].fromCoord ) +
    +                av->correspondence[j - 1].toCoord;
    +              break;
    +            }
    +          }
    +        }
    +      }
     
    -            normalized[i] =
    -              FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord,
    -                         av->correspondence[j].toCoord -
    -                           av->correspondence[j - 1].toCoord,
    -                         av->correspondence[j].fromCoord -
    -                           av->correspondence[j - 1].fromCoord ) +
    -              av->correspondence[j - 1].toCoord;
    -            break;
    +      if ( table->itemStore.varData )
    +      {
    +        if ( FT_QNEW_ARRAY( new_normalized, mmvar->num_axis ) )
    +          return;
    +
    +        /* Install our half-normalized coordinates for the next */
    +        /* Item Variation Store to work with.                   */
    +        old_normalized                = face->blend->normalizedcoords;
    +        face->blend->normalizedcoords = normalized;
    +
    +        for ( i = 0; i < mmvar->num_axis; i++ )
    +        {
    +          FT_Fixed  v          = normalized[i];
    +          FT_UInt   innerIndex = i;
    +          FT_UInt   outerIndex = 0;
    +          FT_Int    delta;
    +
    +
    +          if ( table->axisMap.innerIndex )
    +          {
    +            FT_UInt  idx = i;
    +
    +
    +            if ( idx >= table->axisMap.mapCount )
    +              idx = table->axisMap.mapCount - 1;
    +
    +            outerIndex = table->axisMap.outerIndex[idx];
    +            innerIndex = table->axisMap.innerIndex[idx];
               }
    +
    +          delta = tt_var_get_item_delta( face,
    +                                         &table->itemStore,
    +                                         outerIndex,
    +                                         innerIndex );
    +
    +      v += delta << 2;
    +
    +      /* Clamp value range. */
    +      v = v >=  0x10000L ?  0x10000 : v;
    +      v = v <= -0x10000L ? -0x10000 : v;
    +
    +          new_normalized[i] = v;
             }
    +
    +        for ( i = 0; i < mmvar->num_axis; i++ )
    +        {
    +          normalized[i] = new_normalized[i];
    +        }
    +
    +        face->blend->normalizedcoords = old_normalized;
    +
    +        FT_FREE( new_normalized );
           }
         }
       }
    @@ -2003,9 +2158,9 @@
         for ( ; i < num_coords; i++ )
           design[i] = 0;
     
    -    if ( blend->avar_segment )
    +    if ( blend->avar_table && blend->avar_table->avar_segment )
         {
    -      GX_AVarSegment  av = blend->avar_segment;
    +      GX_AVarSegment  av = blend->avar_table->avar_segment;
     
     
           FT_TRACE5(( "design coordinates"
    @@ -2025,7 +2180,7 @@
                                av->correspondence[j - 1].toCoord ) +
                   av->correspondence[j - 1].fromCoord;
     
    -            FT_TRACE5(( "  %.5f\n", design[i] / 65536.0 ));
    +            FT_TRACE5(( "  %.5f\n", (double)design[i] / 65536 ));
                 break;
               }
             }
    @@ -2170,6 +2325,11 @@
           FT_FRAME_END
         };
     
    +    /* `num_instances` holds the number of all named instances including  */
    +    /* the default instance, which might be missing in the table of named */
    +    /* instances (in 'fvar').  This value is validated in `sfobjs.c` and  */
    +    /* may be reset to 0 if consistency checks fail.                      */
    +    num_instances = (FT_UInt)face->root.style_flags >> 16;
     
         /* read the font data and set up the internal representation */
         /* if not already done                                       */
    @@ -2180,20 +2340,6 @@
         {
           FT_TRACE2(( "FVAR " ));
     
    -      /* both `fvar' and `gvar' must be present */
    -      if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar,
    -                                           stream, &table_len ) ) )
    -      {
    -        /* CFF2 is an alternate to gvar here */
    -        if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2,
    -                                             stream, &table_len ) ) )
    -        {
    -          FT_TRACE1(( "\n" ));
    -          FT_TRACE1(( "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" ));
    -          goto Exit;
    -        }
    -      }
    -
           if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar,
                                                stream, &table_len ) ) )
           {
    @@ -2208,6 +2354,17 @@
           if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) )
             goto Exit;
     
    +      /* If `num_instances` is larger, synthetization of the default  */
    +      /* instance is required.  If `num_instances` is smaller,        */
    +      /* however, the value has been reset to 0 in `sfnt_init_face`   */
    +      /* (in `sfobjs.c`); in this case we have underallocated `mmvar` */
    +      /* structs.                                                     */
    +      if ( num_instances < fvar_head.instanceCount )
    +      {
    +        error = FT_THROW( Invalid_Table );
    +        goto Exit;
    +      }
    +
           usePsName = FT_BOOL( fvar_head.instanceSize ==
                                6 + 4 * fvar_head.axisCount );
     
    @@ -2226,11 +2383,6 @@
         else
           num_axes = face->blend->num_axis;
     
    -    /* `num_instances' holds the number of all named instances, */
    -    /* including the default instance which might be missing    */
    -    /* in fvar's table of named instances                       */
    -    num_instances = (FT_UInt)face->root.style_flags >> 16;
    -
         /* prepare storage area for MM data; this cannot overflow   */
         /* 32-bit arithmetic because of the size limits used in the */
         /* `fvar' table validity check in `sfnt_init_face'          */
    @@ -2358,9 +2510,9 @@
                         "  %10.5f  %10.5f  %10.5f  0x%04X%s\n",
                         i,
                         a->name,
    -                    a->minimum / 65536.0,
    -                    a->def / 65536.0,
    -                    a->maximum / 65536.0,
    +                    (double)a->minimum / 65536,
    +                    (double)a->def / 65536,
    +                    (double)a->maximum / 65536,
                         *axis_flags,
                         invalid ? " (invalid, disabled)" : "" ));
     #endif
    @@ -2561,6 +2713,8 @@
               a->name = (char*)"OpticalSize";
             else if ( a->tag == TTAG_slnt )
               a->name = (char*)"Slant";
    +        else if ( a->tag == TTAG_ital )
    +          a->name = (char*)"Italic";
     
             next_name += 5;
             a++;
    @@ -2622,11 +2776,11 @@
     
         for ( i = 0; i < num_coords; i++ )
         {
    -      FT_TRACE5(( "    %.5f\n", coords[i] / 65536.0 ));
    +      FT_TRACE5(( "    %.5f\n", (double)coords[i] / 65536 ));
           if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L )
           {
             FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n",
    -                    coords[i] / 65536.0 ));
    +                    (double)coords[i] / 65536 ));
             FT_TRACE1(( "                 is out of range [-1;1]\n" ));
             error = FT_THROW( Invalid_Argument );
             goto Exit;
    @@ -2636,8 +2790,16 @@
         FT_TRACE5(( "\n" ));
     
         if ( !face->is_cff2 && !blend->glyphoffsets )
    -      if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) )
    +    {
    +      /* While a missing 'gvar' table is acceptable, for example for */
    +      /* fonts that only vary metrics information or 'COLR' v1       */
    +      /* `PaintVar*` tables, an incorrect SFNT table offset or size  */
    +      /* for 'gvar', or an inconsistent 'gvar' table is not.         */
    +      error = ft_var_load_gvar( face );
    +      if ( error != FT_Err_Table_Missing && error != FT_Err_Ok )
             goto Exit;
    +      error = FT_Err_Ok;
    +    }
     
         if ( !blend->coords )
         {
    @@ -3503,10 +3665,10 @@
               {
                 FT_TRACE7(( "      %d: %f -> %f\n",
                             j,
    -                        ( FT_fdot6ToFixed( face->cvt[j] ) +
    -                          old_cvt_delta ) / 65536.0,
    -                        ( FT_fdot6ToFixed( face->cvt[j] ) +
    -                          cvt_deltas[j] ) / 65536.0 ));
    +                        (double)( FT_fdot6ToFixed( face->cvt[j] ) +
    +                                    old_cvt_delta ) / 65536,
    +                        (double)( FT_fdot6ToFixed( face->cvt[j] ) +
    +                                    cvt_deltas[j] ) / 65536 ));
                 count++;
               }
     #endif
    @@ -3545,10 +3707,10 @@
               {
                 FT_TRACE7(( "      %d: %f -> %f\n",
                             pindex,
    -                        ( FT_fdot6ToFixed( face->cvt[pindex] ) +
    -                          old_cvt_delta ) / 65536.0,
    -                        ( FT_fdot6ToFixed( face->cvt[pindex] ) +
    -                          cvt_deltas[pindex] ) / 65536.0 ));
    +                        (double)( FT_fdot6ToFixed( face->cvt[pindex] ) +
    +                                    old_cvt_delta ) / 65536,
    +                        (double)( FT_fdot6ToFixed( face->cvt[pindex] ) +
    +                                    cvt_deltas[pindex] ) / 65536 ));
                 count++;
               }
     #endif
    @@ -3813,20 +3975,12 @@
        * @Description:
        *   Apply the appropriate deltas to the current glyph.
        *
    -   * @Input:
    -   *   face ::
    -   *     A handle to the target face object.
    -   *
    -   *   glyph_index ::
    -   *     The index of the glyph being modified.
    -   *
    -   *   n_points ::
    -   *     The number of the points in the glyph, including
    -   *     phantom points.
    -   *
        * @InOut:
    +   *   loader ::
    +   *     A handle to the loader object.
    +   *
        *   outline ::
    -   *     The outline to change.
    +   *     The outline to change, with appended phantom points.
        *
        * @Output:
        *   unrounded ::
    @@ -3837,15 +3991,16 @@
        *   FreeType error code.  0 means success.
        */
       FT_LOCAL_DEF( FT_Error )
    -  TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
    -                              FT_UInt      glyph_index,
    +  TT_Vary_Apply_Glyph_Deltas( TT_Loader    loader,
                                   FT_Outline*  outline,
    -                              FT_Vector*   unrounded,
    -                              FT_UInt      n_points )
    +                              FT_Vector*   unrounded )
       {
         FT_Error   error;
    -    FT_Stream  stream = face->root.stream;
    -    FT_Memory  memory = stream->memory;
    +    TT_Face    face        = loader->face;
    +    FT_Stream  stream      = face->root.stream;
    +    FT_Memory  memory      = stream->memory;
    +    FT_UInt    glyph_index = loader->glyph_index;
    +    FT_UInt    n_points    = (FT_UInt)outline->n_points + 4;
     
         FT_Vector*  points_org = NULL;  /* coordinates in 16.16 format */
         FT_Vector*  points_out = NULL;  /* coordinates in 16.16 format */
    @@ -4063,50 +4218,22 @@
               FT_Fixed  point_delta_y = FT_MulFix( deltas_y[j], apply );
     
     
    -          if ( j < n_points - 4 )
    -          {
    -            point_deltas_x[j] = old_point_delta_x + point_delta_x;
    -            point_deltas_y[j] = old_point_delta_y + point_delta_y;
    -          }
    -          else
    -          {
    -            /* To avoid double adjustment of advance width or height, */
    -            /* adjust phantom points only if there is no HVAR or VVAR */
    -            /* support, respectively.                                 */
    -            if ( j == ( n_points - 4 )        &&
    -                 !( face->variation_support &
    -                    TT_FACE_FLAG_VAR_LSB    ) )
    -              point_deltas_x[j] = old_point_delta_x + point_delta_x;
    -
    -            else if ( j == ( n_points - 3 )          &&
    -                      !( face->variation_support   &
    -                         TT_FACE_FLAG_VAR_HADVANCE ) )
    -              point_deltas_x[j] = old_point_delta_x + point_delta_x;
    -
    -            else if ( j == ( n_points - 2 )        &&
    -                      !( face->variation_support &
    -                         TT_FACE_FLAG_VAR_TSB    ) )
    -              point_deltas_y[j] = old_point_delta_y + point_delta_y;
    -
    -            else if ( j == ( n_points - 1 )          &&
    -                      !( face->variation_support   &
    -                         TT_FACE_FLAG_VAR_VADVANCE ) )
    -              point_deltas_y[j] = old_point_delta_y + point_delta_y;
    -          }
    +          point_deltas_x[j] = old_point_delta_x + point_delta_x;
    +          point_deltas_y[j] = old_point_delta_y + point_delta_y;
     
     #ifdef FT_DEBUG_LEVEL_TRACE
               if ( point_delta_x || point_delta_y )
               {
                 FT_TRACE7(( "      %d: (%f, %f) -> (%f, %f)\n",
                             j,
    -                        ( FT_intToFixed( outline->points[j].x ) +
    -                          old_point_delta_x ) / 65536.0,
    -                        ( FT_intToFixed( outline->points[j].y ) +
    -                          old_point_delta_y ) / 65536.0,
    -                        ( FT_intToFixed( outline->points[j].x ) +
    -                          point_deltas_x[j] ) / 65536.0,
    -                        ( FT_intToFixed( outline->points[j].y ) +
    -                          point_deltas_y[j] ) / 65536.0 ));
    +                        (double)( FT_intToFixed( outline->points[j].x ) +
    +                                    old_point_delta_x ) / 65536,
    +                        (double)( FT_intToFixed( outline->points[j].y ) +
    +                                    old_point_delta_y ) / 65536,
    +                        (double)( FT_intToFixed( outline->points[j].x ) +
    +                                    point_deltas_x[j] ) / 65536,
    +                        (double)( FT_intToFixed( outline->points[j].y ) +
    +                                    point_deltas_y[j] ) / 65536 ));
                 count++;
               }
     #endif
    @@ -4165,50 +4292,22 @@
               FT_Pos  point_delta_y = points_out[j].y - points_org[j].y;
     
     
    -          if ( j < n_points - 4 )
    -          {
    -            point_deltas_x[j] = old_point_delta_x + point_delta_x;
    -            point_deltas_y[j] = old_point_delta_y + point_delta_y;
    -          }
    -          else
    -          {
    -            /* To avoid double adjustment of advance width or height, */
    -            /* adjust phantom points only if there is no HVAR or VVAR */
    -            /* support, respectively.                                 */
    -            if ( j == ( n_points - 4 )        &&
    -                 !( face->variation_support &
    -                    TT_FACE_FLAG_VAR_LSB    ) )
    -              point_deltas_x[j] = old_point_delta_x + point_delta_x;
    -
    -            else if ( j == ( n_points - 3 )          &&
    -                      !( face->variation_support   &
    -                         TT_FACE_FLAG_VAR_HADVANCE ) )
    -              point_deltas_x[j] = old_point_delta_x + point_delta_x;
    -
    -            else if ( j == ( n_points - 2 )        &&
    -                      !( face->variation_support &
    -                         TT_FACE_FLAG_VAR_TSB    ) )
    -              point_deltas_y[j] = old_point_delta_y + point_delta_y;
    -
    -            else if ( j == ( n_points - 1 )          &&
    -                      !( face->variation_support   &
    -                         TT_FACE_FLAG_VAR_VADVANCE ) )
    -              point_deltas_y[j] = old_point_delta_y + point_delta_y;
    -          }
    +          point_deltas_x[j] = old_point_delta_x + point_delta_x;
    +          point_deltas_y[j] = old_point_delta_y + point_delta_y;
     
     #ifdef FT_DEBUG_LEVEL_TRACE
               if ( point_delta_x || point_delta_y )
               {
                 FT_TRACE7(( "      %d: (%f, %f) -> (%f, %f)\n",
                             j,
    -                        ( FT_intToFixed( outline->points[j].x ) +
    -                          old_point_delta_x ) / 65536.0,
    -                        ( FT_intToFixed( outline->points[j].y ) +
    -                          old_point_delta_y ) / 65536.0,
    -                        ( FT_intToFixed( outline->points[j].x ) +
    -                          point_deltas_x[j] ) / 65536.0,
    -                        ( FT_intToFixed( outline->points[j].y ) +
    -                          point_deltas_y[j] ) / 65536.0 ));
    +                        (double)( FT_intToFixed( outline->points[j].x ) +
    +                                    old_point_delta_x ) / 65536,
    +                        (double)( FT_intToFixed( outline->points[j].y ) +
    +                                    old_point_delta_y ) / 65536,
    +                        (double)( FT_intToFixed( outline->points[j].x ) +
    +                                    point_deltas_x[j] ) / 65536,
    +                        (double)( FT_intToFixed( outline->points[j].y ) +
    +                                    point_deltas_y[j] ) / 65536 ));
                 count++;
               }
     #endif
    @@ -4232,6 +4331,24 @@
     
         FT_TRACE5(( "\n" ));
     
    +    /* To avoid double adjustment of advance width or height, */
    +    /* do not move phantom points if there is HVAR or VVAR    */
    +    /* support, respectively.                                 */
    +    if ( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE )
    +    {
    +      point_deltas_x[n_points - 4] = 0;
    +      point_deltas_y[n_points - 4] = 0;
    +      point_deltas_x[n_points - 3] = 0;
    +      point_deltas_y[n_points - 3] = 0;
    +    }
    +    if ( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE )
    +    {
    +      point_deltas_x[n_points - 2] = 0;
    +      point_deltas_y[n_points - 2] = 0;
    +      point_deltas_x[n_points - 1] = 0;
    +      point_deltas_y[n_points - 1] = 0;
    +    }
    +
         for ( i = 0; i < n_points; i++ )
         {
           unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] );
    @@ -4241,6 +4358,24 @@
           outline->points[i].y += FT_fixedToInt( point_deltas_y[i] );
         }
     
    +    /* To avoid double adjustment of advance width or height, */
    +    /* adjust phantom points only if there is no HVAR or VVAR */
    +    /* support, respectively.                                 */
    +    if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
    +    {
    +      loader->pp1      = outline->points[n_points - 4];
    +      loader->pp2      = outline->points[n_points - 3];
    +      loader->linear   = FT_PIX_ROUND( unrounded[n_points - 3].x -
    +                                       unrounded[n_points - 4].x ) / 64;
    +    }
    +    if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
    +    {
    +      loader->pp3      = outline->points[n_points - 2];
    +      loader->pp4      = outline->points[n_points - 1];
    +      loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].y -
    +                                       unrounded[n_points - 2].y ) / 64;
    +    }
    +
       Fail3:
         FT_FREE( point_deltas_x );
         FT_FREE( point_deltas_y );
    @@ -4305,8 +4440,8 @@
       }
     
     
    -  static void
    -  ft_var_done_item_variation_store( TT_Face          face,
    +  FT_LOCAL_DEF( void )
    +  tt_var_done_item_variation_store( TT_Face          face,
                                         GX_ItemVarStore  itemStore )
       {
         FT_Memory  memory = FT_FACE_MEMORY( face );
    @@ -4334,6 +4469,18 @@
       }
     
     
    +  FT_LOCAL_DEF( void )
    +  tt_var_done_delta_set_index_map( TT_Face            face,
    +                                   GX_DeltaSetIdxMap  deltaSetIdxMap )
    +  {
    +    FT_Memory  memory = FT_FACE_MEMORY( face );
    +
    +
    +    FT_FREE( deltaSetIdxMap->innerIndex );
    +    FT_FREE( deltaSetIdxMap->outerIndex );
    +  }
    +
    +
       /**************************************************************************
        *
        * @Function:
    @@ -4362,36 +4509,47 @@
           FT_FREE( blend->normalized_stylecoords );
           FT_FREE( blend->mmvar );
     
    -      if ( blend->avar_segment )
    +      if ( blend->avar_table )
           {
    -        for ( i = 0; i < num_axes; i++ )
    -          FT_FREE( blend->avar_segment[i].correspondence );
    -        FT_FREE( blend->avar_segment );
    +        if ( blend->avar_table->avar_segment )
    +        {
    +          for ( i = 0; i < num_axes; i++ )
    +            FT_FREE( blend->avar_table->avar_segment[i].correspondence );
    +          FT_FREE( blend->avar_table->avar_segment );
    +        }
    +
    +        tt_var_done_item_variation_store( face,
    +                                          &blend->avar_table->itemStore );
    +
    +        tt_var_done_delta_set_index_map( face,
    +                                         &blend->avar_table->axisMap );
    +
    +        FT_FREE( blend->avar_table );
           }
     
           if ( blend->hvar_table )
           {
    -        ft_var_done_item_variation_store( face,
    +        tt_var_done_item_variation_store( face,
                                               &blend->hvar_table->itemStore );
     
    -        FT_FREE( blend->hvar_table->widthMap.innerIndex );
    -        FT_FREE( blend->hvar_table->widthMap.outerIndex );
    +        tt_var_done_delta_set_index_map( face,
    +                                         &blend->hvar_table->widthMap );
             FT_FREE( blend->hvar_table );
           }
     
           if ( blend->vvar_table )
           {
    -        ft_var_done_item_variation_store( face,
    +        tt_var_done_item_variation_store( face,
                                               &blend->vvar_table->itemStore );
     
    -        FT_FREE( blend->vvar_table->widthMap.innerIndex );
    -        FT_FREE( blend->vvar_table->widthMap.outerIndex );
    +        tt_var_done_delta_set_index_map( face,
    +                                         &blend->vvar_table->widthMap );
             FT_FREE( blend->vvar_table );
           }
     
           if ( blend->mvar_table )
           {
    -        ft_var_done_item_variation_store( face,
    +        tt_var_done_item_variation_store( face,
                                               &blend->mvar_table->itemStore );
     
             FT_FREE( blend->mvar_table->values );
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType GX Font Variation loader (specification)
      *
    - * Copyright (C) 2004-2022 by
    + * Copyright (C) 2004-2023 by
      * David Turner, Robert Wilhelm, Werner Lemberg and George Williams.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -20,6 +20,7 @@
     #define TTGXVAR_H_
     
     
    +#include 
     #include "ttobjs.h"
     
     
    @@ -62,55 +63,21 @@
       } GX_AVarSegmentRec, *GX_AVarSegment;
     
     
    -  typedef struct  GX_ItemVarDataRec_
    -  {
    -    FT_UInt    itemCount;      /* number of delta sets per item         */
    -    FT_UInt    regionIdxCount; /* number of region indices in this data */
    -    FT_UInt*   regionIndices;  /* array of `regionCount' indices;       */
    -                               /* these index `varRegionList'           */
    -    FT_Short*  deltaSet;       /* array of `itemCount' deltas           */
    -                               /* use `innerIndex' for this array       */
    -
    -  } GX_ItemVarDataRec, *GX_ItemVarData;
    -
    -
    -  /* contribution of one axis to a region */
    -  typedef struct  GX_AxisCoordsRec_
    -  {
    -    FT_Fixed  startCoord;
    -    FT_Fixed  peakCoord;      /* zero means no effect (factor = 1) */
    -    FT_Fixed  endCoord;
    -
    -  } GX_AxisCoordsRec, *GX_AxisCoords;
    -
    -
    -  typedef struct  GX_VarRegionRec_
    -  {
    -    GX_AxisCoords  axisList;               /* array of axisCount records */
    -
    -  } GX_VarRegionRec, *GX_VarRegion;
    -
    -
    -  /* item variation store */
    -  typedef struct  GX_ItemVarStoreRec_
    -  {
    -    FT_UInt         dataCount;
    -    GX_ItemVarData  varData;            /* array of dataCount records;     */
    -                                        /* use `outerIndex' for this array */
    -    FT_UShort     axisCount;
    -    FT_UInt       regionCount;          /* total number of regions defined */
    -    GX_VarRegion  varRegionList;
    -
    -  } GX_ItemVarStoreRec, *GX_ItemVarStore;
    -
    -
    -  typedef struct  GX_DeltaSetIdxMapRec_
    +  /**************************************************************************
    +   *
    +   * @Struct:
    +   *   GX_AVarTableRec
    +   *
    +   * @Description:
    +   *   Data from the `avar' table.
    +   */
    +  typedef struct  GX_AVarTableRec_
       {
    -    FT_ULong  mapCount;
    -    FT_UInt*  outerIndex;               /* indices to item var data */
    -    FT_UInt*  innerIndex;               /* indices to delta set     */
    +    GX_AVarSegment        avar_segment;   /* avar_segment[num_axis] */
    +    GX_ItemVarStoreRec    itemStore;      /* Item Variation Store   */
    +    GX_DeltaSetIdxMapRec  axisMap;        /* Axis Mapping           */
     
    -  } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap;
    +  } GX_AVarTableRec, *GX_AVarTable;
     
     
       /**************************************************************************
    @@ -245,7 +212,7 @@
        *     A Boolean; if set, FreeType tried to load (and parse) the `avar'
        *     table.
        *
    -   *   avar_segment ::
    +   *   avar_table ::
        *     Data from the `avar' table.
        *
        *   hvar_loaded ::
    @@ -310,7 +277,7 @@
                           /* normalized_stylecoords[num_namedstyles][num_axis] */
     
         FT_Bool         avar_loaded;
    -    GX_AVarSegment  avar_segment;                /* avar_segment[num_axis] */
    +    GX_AVarTable    avar_table;
     
         FT_Bool         hvar_loaded;
         FT_Bool         hvar_checked;
    @@ -376,6 +343,7 @@
     #define TTAG_wdth  FT_MAKE_TAG( 'w', 'd', 't', 'h' )
     #define TTAG_opsz  FT_MAKE_TAG( 'o', 'p', 's', 'z' )
     #define TTAG_slnt  FT_MAKE_TAG( 's', 'l', 'n', 't' )
    +#define TTAG_ital  FT_MAKE_TAG( 'i', 't', 'a', 'l' )
     
     
       FT_LOCAL( FT_Error )
    @@ -412,11 +380,9 @@
     
     
       FT_LOCAL( FT_Error )
    -  TT_Vary_Apply_Glyph_Deltas( TT_Face      face,
    -                              FT_UInt      glyph_index,
    +  TT_Vary_Apply_Glyph_Deltas( TT_Loader    loader,
                                   FT_Outline*  outline,
    -                              FT_Vector*   unrounded,
    -                              FT_UInt      n_points );
    +                              FT_Vector*   unrounded );
     
       FT_LOCAL( FT_Error )
       tt_hadvance_adjust( TT_Face  face,
    @@ -431,6 +397,34 @@
       FT_LOCAL( void )
       tt_apply_mvar( TT_Face  face );
     
    +
    +  FT_LOCAL( FT_Error )
    +  tt_var_load_item_variation_store( TT_Face          face,
    +                                    FT_ULong         offset,
    +                                    GX_ItemVarStore  itemStore );
    +
    +  FT_LOCAL( FT_Error )
    +  tt_var_load_delta_set_index_mapping( TT_Face            face,
    +                                       FT_ULong           offset,
    +                                       GX_DeltaSetIdxMap  map,
    +                                       GX_ItemVarStore    itemStore,
    +                                       FT_ULong           table_len );
    +
    +  FT_LOCAL( FT_ItemVarDelta )
    +  tt_var_get_item_delta( TT_Face          face,
    +                         GX_ItemVarStore  itemStore,
    +                         FT_UInt          outerIndex,
    +                         FT_UInt          innerIndex );
    +
    +  FT_LOCAL( void )
    +  tt_var_done_item_variation_store( TT_Face          face,
    +                                    GX_ItemVarStore  itemStore );
    +
    +  FT_LOCAL( void )
    +  tt_var_done_delta_set_index_map( TT_Face            face,
    +                                   GX_DeltaSetIdxMap  deltaSetIdxMap );
    +
    +
       FT_LOCAL( FT_Error )
       tt_get_var_blend( TT_Face      face,
                         FT_UInt     *num_coords,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType bytecode interpreter (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1527,9 +1527,8 @@
       static void
       Modify_CVT_Check( TT_ExecContext  exc )
       {
    -    /* TT_RunIns sets origCvt and restores cvt to origCvt when done. */
         if ( exc->iniRange == tt_coderange_glyph &&
    -         exc->cvt == exc->origCvt            )
    +         exc->cvt != exc->glyfCvt            )
         {
           exc->error = Update_Max( exc->memory,
                                    &exc->glyfCvtSize,
    @@ -3115,10 +3114,8 @@
         }
         else
         {
    -      /* TT_RunIns sets origStorage and restores storage to origStorage */
    -      /* when done.                                                     */
           if ( exc->iniRange == tt_coderange_glyph &&
    -           exc->storage == exc->origStorage    )
    +           exc->storage != exc->glyfStorage    )
           {
             FT_ULong  tmp = (FT_ULong)exc->glyfStoreSize;
     
    @@ -6874,7 +6871,7 @@
     
     
       static void
    -  _iup_worker_shift( IUP_Worker  worker,
    +  iup_worker_shift_( IUP_Worker  worker,
                          FT_UInt     p1,
                          FT_UInt     p2,
                          FT_UInt     p )
    @@ -6896,7 +6893,7 @@
     
     
       static void
    -  _iup_worker_interpolate( IUP_Worker  worker,
    +  iup_worker_interpolate_( IUP_Worker  worker,
                                FT_UInt     p1,
                                FT_UInt     p2,
                                FT_UInt     ref1,
    @@ -7090,7 +7087,7 @@
             {
               if ( ( exc->pts.tags[point] & mask ) != 0 )
               {
    -            _iup_worker_interpolate( &V,
    +            iup_worker_interpolate_( &V,
                                          cur_touched + 1,
                                          point - 1,
                                          cur_touched,
    @@ -7102,17 +7099,17 @@
             }
     
             if ( cur_touched == first_touched )
    -          _iup_worker_shift( &V, first_point, end_point, cur_touched );
    +          iup_worker_shift_( &V, first_point, end_point, cur_touched );
             else
             {
    -          _iup_worker_interpolate( &V,
    +          iup_worker_interpolate_( &V,
                                        (FT_UShort)( cur_touched + 1 ),
                                        end_point,
                                        cur_touched,
                                        first_touched );
     
               if ( first_touched > 0 )
    -            _iup_worker_interpolate( &V,
    +            iup_worker_interpolate_( &V,
                                          first_point,
                                          first_touched - 1,
                                          cur_touched,
    @@ -7832,8 +7829,6 @@
           exc->func_move_cvt  = Move_CVT;
         }
     
    -    exc->origCvt     = exc->cvt;
    -    exc->origStorage = exc->storage;
         exc->iniRange    = exc->curRange;
     
         Compute_Funcs( exc );
    @@ -8570,7 +8565,8 @@
     
           /* increment instruction counter and check if we didn't */
           /* run this program for too long (e.g. infinite loops). */
    -      if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) {
    +      if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES )
    +      {
             exc->error = FT_THROW( Execution_Too_Long );
             goto LErrorLabel_;
           }
    @@ -8593,9 +8589,6 @@
                     ins_counter,
                     ins_counter == 1 ? "" : "s" ));
     
    -    exc->cvt     = exc->origCvt;
    -    exc->storage = exc->origStorage;
    -
         return FT_Err_Ok;
     
       LErrorCodeOverflow_:
    @@ -8605,9 +8598,6 @@
         if ( exc->error && !exc->instruction_trap )
           FT_TRACE1(( "  The interpreter returned error 0x%x\n", exc->error ));
     
    -    exc->cvt     = exc->origCvt;
    -    exc->storage = exc->origStorage;
    -
         return exc->error;
       }
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType bytecode interpreter (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -193,7 +193,6 @@
         FT_Long*           cvt;       /* ! */
         FT_ULong           glyfCvtSize;
         FT_Long*           glyfCvt;   /* cvt working copy for glyph */
    -    FT_Long*           origCvt;
     
         FT_UInt            glyphSize; /* ! glyph instructions buffer size */
         FT_Byte*           glyphIns;  /* ! glyph instructions buffer      */
    @@ -224,7 +223,6 @@
         FT_Long*           storage;      /* ! storage area            */
         FT_UShort          glyfStoreSize;
         FT_Long*           glyfStorage;  /* storage working copy for glyph */
    -    FT_Long*           origStorage;
     
         FT_F26Dot6         period;     /* values used for the */
         FT_F26Dot6         phase;      /* `SuperRounding'     */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Objects manager (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -1004,7 +1004,7 @@
         {
           size->cvt[i] = FT_MulFix( face->cvt[i], scale );
           FT_TRACE6(( "  %3d: %f (%f)\n",
    -                  i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 ));
    +                  i, (double)face->cvt[i] / 64, (double)size->cvt[i] / 64 ));
         }
         FT_TRACE6(( "\n" ));
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Objects manager (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType-specific tables loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType-specific tables loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType Subpixel Hinting.
      *
    - * Copyright (C) 2010-2022 by
    + * Copyright (C) 2010-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/truetype/ttsubpix.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   TrueType Subpixel Hinting.
      *
    - * Copyright (C) 2010-2022 by
    + * Copyright (C) 2010-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   AFM support for Type 1 fonts (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -178,7 +178,6 @@
         /* temporarily.  If we find no PostScript charmap, then just use    */
         /* the default and hope it is the right one.                        */
         oldcharmap = t1_face->charmap;
    -    charmap    = NULL;
     
         for ( n = 0; n < t1_face->num_charmaps; n++ )
         {
    @@ -186,9 +185,7 @@
           /* check against PostScript pseudo platform */
           if ( charmap->platform_id == 7 )
           {
    -        error = FT_Set_Charmap( t1_face, charmap );
    -        if ( error )
    -          goto Exit;
    +        t1_face->charmap = charmap;
             break;
           }
         }
    @@ -209,10 +206,7 @@
           kp++;
         }
     
    -    if ( oldcharmap )
    -      error = FT_Set_Charmap( t1_face, oldcharmap );
    -    if ( error )
    -      goto Exit;
    +    t1_face->charmap = oldcharmap;
     
         /* now, sort the kern pairs according to their glyph indices */
         ft_qsort( fi->KernPairs, fi->NumKernPair, sizeof ( AFM_KernPairRec ),
    @@ -302,9 +296,14 @@
           t1_face->bbox.xMax = ( fi->FontBBox.xMax + 0xFFFF ) >> 16;
           t1_face->bbox.yMax = ( fi->FontBBox.yMax + 0xFFFF ) >> 16;
     
    -      /* no `U' suffix here to 0x8000! */
    -      t1_face->ascender  = (FT_Short)( ( fi->Ascender  + 0x8000 ) >> 16 );
    -      t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );
    +      /* ascender and descender are optional and could both be zero */
    +      /* check if values are meaningful before overriding defaults  */
    +      if ( fi->Ascender > fi->Descender )
    +      {
    +        /* no `U' suffix here to 0x8000! */
    +        t1_face->ascender  = (FT_Short)( ( fi->Ascender  + 0x8000 ) >> 16 );
    +        t1_face->descender = (FT_Short)( ( fi->Descender + 0x8000 ) >> 16 );
    +      }
     
           if ( fi->NumKernPair )
           {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1afm.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   AFM support for Type 1 fonts (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 driver interface (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -121,19 +121,30 @@
     #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
       static const FT_Service_MultiMastersRec  t1_service_multi_masters =
       {
    -    (FT_Get_MM_Func)             T1_Get_Multi_Master,    /* get_mm              */
    -    (FT_Set_MM_Design_Func)      T1_Set_MM_Design,       /* set_mm_design       */
    -    (FT_Set_MM_Blend_Func)       T1_Set_MM_Blend,        /* set_mm_blend        */
    -    (FT_Get_MM_Blend_Func)       T1_Get_MM_Blend,        /* get_mm_blend        */
    -    (FT_Get_MM_Var_Func)         T1_Get_MM_Var,          /* get_mm_var          */
    -    (FT_Set_Var_Design_Func)     T1_Set_Var_Design,      /* set_var_design      */
    -    (FT_Get_Var_Design_Func)     T1_Get_Var_Design,      /* get_var_design      */
    -    (FT_Set_Instance_Func)       T1_Reset_MM_Blend,      /* set_instance        */
    -    (FT_Set_MM_WeightVector_Func)T1_Set_MM_WeightVector, /* set_mm_weightvector */
    -    (FT_Get_MM_WeightVector_Func)T1_Get_MM_WeightVector, /* get_mm_weightvector */
    -
    -    (FT_Get_Var_Blend_Func)      NULL,                   /* get_var_blend       */
    -    (FT_Done_Blend_Func)         T1_Done_Blend           /* done_blend          */
    +    (FT_Get_MM_Func)        T1_Get_Multi_Master,    /* get_mm                    */
    +    (FT_Set_MM_Design_Func) T1_Set_MM_Design,       /* set_mm_design             */
    +    (FT_Set_MM_Blend_Func)  T1_Set_MM_Blend,        /* set_mm_blend              */
    +    (FT_Get_MM_Blend_Func)  T1_Get_MM_Blend,        /* get_mm_blend              */
    +    (FT_Get_MM_Var_Func)    T1_Get_MM_Var,          /* get_mm_var                */
    +    (FT_Set_Var_Design_Func)T1_Set_Var_Design,      /* set_var_design            */
    +    (FT_Get_Var_Design_Func)T1_Get_Var_Design,      /* get_var_design            */
    +    (FT_Set_Instance_Func)  T1_Reset_MM_Blend,      /* set_instance              */
    +    (FT_Set_MM_WeightVector_Func)
    +                            T1_Set_MM_WeightVector, /* set_mm_weightvector       */
    +    (FT_Get_MM_WeightVector_Func)
    +                            T1_Get_MM_WeightVector, /* get_mm_weightvector       */
    +    (FT_Var_Load_Delta_Set_Idx_Map_Func)
    +                            NULL,                   /* load_delta_set_idx_map    */
    +    (FT_Var_Load_Item_Var_Store_Func)
    +                            NULL,                   /* load_item_variation_store */
    +    (FT_Var_Get_Item_Delta_Func)
    +                            NULL,                   /* get_item_delta            */
    +    (FT_Var_Done_Item_Var_Store_Func)
    +                            NULL,                   /* done_item_variation_store */
    +    (FT_Var_Done_Delta_Set_Idx_Map_Func)
    +                            NULL,                   /* done_delta_set_index_map  */
    +    (FT_Get_Var_Blend_Func) NULL,                   /* get_var_blend             */
    +    (FT_Done_Blend_Func)    T1_Done_Blend           /* done_blend                */
       };
     #endif
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1driver.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   High-level Type 1 driver interface (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1errors.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 error codes (specification only).
      *
    - * Copyright (C) 2001-2022 by
    + * Copyright (C) 2001-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1gload.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 Glyph Loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -264,7 +264,7 @@
         }
     
         FT_TRACE6(( "T1_Compute_Max_Advance: max advance: %f\n",
    -                *max_advance / 65536.0 ));
    +                (double)*max_advance / 65536 ));
     
         psaux->t1_decoder_funcs->done( &decoder );
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1gload.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 Glyph Loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1load.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1load.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1load.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1load.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 font loader (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -355,6 +355,10 @@
             mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
           else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
             mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
    +      else if ( ft_strcmp( mmvar->axis[i].name, "Slant" ) == 0 )
    +        mmvar->axis[i].tag = FT_MAKE_TAG( 's', 'l', 'n', 't' );
    +      else if ( ft_strcmp( mmvar->axis[i].name, "Italic" ) == 0 )
    +        mmvar->axis[i].tag = FT_MAKE_TAG( 'i', 't', 'a', 'l' );
         }
     
         mm_weights_unmap( blend->default_weight_vector,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1load.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1load.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1load.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1load.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 font loader (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 objects manager (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -146,7 +146,9 @@
       FT_LOCAL_DEF( void )
       T1_GlyphSlot_Done( FT_GlyphSlot  slot )
       {
    -    slot->internal->glyph_hints = NULL;
    +    /* `slot->internal` might be NULL in out-of-memory situations. */
    +    if ( slot->internal )
    +      slot->internal->glyph_hints = NULL;
       }
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1objs.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 objects manager (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1parse.c	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 parser (body).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    @@ -330,50 +330,25 @@
           /* the private dict.  Otherwise, simply overwrite into the base  */
           /* dictionary block in the heap.                                 */
     
    -      /* first of all, look at the `eexec' keyword */
    +      /* First look for the `eexec' keyword. Ensure `eexec' is real -- */
    +      /* it could be in a comment or string (as e.g. in u003043t.gsf   */
    +      /* from ghostscript).                                            */
           FT_Byte*    cur   = parser->base_dict;
           FT_Byte*    limit = cur + parser->base_len;
           FT_Pointer  pos_lf;
           FT_Bool     test_cr;
     
     
    -    Again:
    -      for (;;)
    -      {
    -        if ( cur[0] == 'e'   &&
    -             cur + 9 < limit )      /* 9 = 5 letters for `eexec' + */
    -                                    /* whitespace + 4 chars        */
    -        {
    -          if ( cur[1] == 'e' &&
    -               cur[2] == 'x' &&
    -               cur[3] == 'e' &&
    -               cur[4] == 'c' )
    -            break;
    -        }
    -        cur++;
    -        if ( cur >= limit )
    -        {
    -          FT_ERROR(( "T1_Get_Private_Dict:"
    -                     " could not find `eexec' keyword\n" ));
    -          error = FT_THROW( Invalid_File_Format );
    -          goto Exit;
    -        }
    -      }
    -
    -      /* check whether `eexec' was real -- it could be in a comment */
    -      /* or string (as e.g. in u003043t.gsf from ghostscript)       */
    -
           parser->root.cursor = parser->base_dict;
    -      /* set limit to `eexec' + whitespace + 4 characters */
    -      parser->root.limit  = cur + 10;
    +      parser->root.limit  = parser->base_dict + parser->base_len;
     
           cur   = parser->root.cursor;
           limit = parser->root.limit;
     
           while ( cur < limit )
           {
    -        if ( cur[0] == 'e'   &&
    -             cur + 5 < limit )
    +        /* 9 = 5 letters for `eexec' + whitespace + 4 chars */
    +        if ( cur[0] == 'e' && cur + 9 < limit )
             {
               if ( cur[1] == 'e' &&
                    cur[2] == 'x' &&
    @@ -389,21 +364,9 @@
             cur = parser->root.cursor;
           }
     
    -      /* we haven't found the correct `eexec'; go back and continue */
    -      /* searching                                                  */
    -
    -      cur   = limit;
    -      limit = parser->base_dict + parser->base_len;
    -
    -      if ( cur >= limit )
    -      {
    -        FT_ERROR(( "T1_Get_Private_Dict:"
    -                   " premature end in private dictionary\n" ));
    -        error = FT_THROW( Invalid_File_Format );
    -        goto Exit;
    -      }
    -
    -      goto Again;
    +      FT_ERROR(( "T1_Get_Private_Dict: could not find `eexec' keyword\n" ));
    +      error = FT_THROW( Invalid_File_Format );
    +      goto Exit;
     
           /* now determine where to write the _encrypted_ binary private  */
           /* dictionary.  We overwrite the base dictionary for disk-based */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1parse.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 parser (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libfreetype/src/type1/t1tokens.h	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,7 @@
      *
      *   Type 1 tokenizer (specification).
      *
    - * Copyright (C) 1996-2022 by
    + * Copyright (C) 1996-2023 by
      * David Turner, Robert Wilhelm, and Werner Lemberg.
      *
      * This file is part of the FreeType project, and may only be used,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -464,7 +464,8 @@
     template 
     struct Entry
     {
    -  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
    +  // This does seem like it's ever called.
    +  bool sanitize (hb_sanitize_context_t *c) const
       {
         TRACE_SANITIZE (this);
         /* Note, we don't recurse-sanitize data because we don't access it.
    @@ -492,7 +493,8 @@
     template <>
     struct Entry
     {
    -  bool sanitize (hb_sanitize_context_t *c, unsigned int count /*XXX Unused?*/) const
    +  // This does seem like it's ever called.
    +  bool sanitize (hb_sanitize_context_t *c) const
       {
         TRACE_SANITIZE (this);
         return_trace (c->check_struct (this));
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-algs.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-algs.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-algs.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-algs.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -110,9 +110,10 @@
       constexpr operator Type () const
       {
     #if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
    -    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
         defined(__BYTE_ORDER) && \
    -    (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
    +    (__BYTE_ORDER == __BIG_ENDIAN || \
    +     (__BYTE_ORDER == __LITTLE_ENDIAN && \
    +      hb_has_builtin(__builtin_bswap16)))
         /* Spoon-feed the compiler a big-endian integer with alignment 1.
          * https://github.com/harfbuzz/harfbuzz/pull/1398 */
     #if __BYTE_ORDER == __LITTLE_ENDIAN
    @@ -155,9 +156,10 @@
       struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
       constexpr operator Type () const {
     #if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
    -    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
         defined(__BYTE_ORDER) && \
    -    (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
    +    (__BYTE_ORDER == __BIG_ENDIAN || \
    +     (__BYTE_ORDER == __LITTLE_ENDIAN && \
    +      hb_has_builtin(__builtin_bswap32)))
         /* Spoon-feed the compiler a big-endian integer with alignment 1.
          * https://github.com/harfbuzz/harfbuzz/pull/1398 */
     #if __BYTE_ORDER == __LITTLE_ENDIAN
    @@ -598,13 +600,17 @@
     static inline unsigned int
     hb_popcount (T v)
     {
    -#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
    +#if hb_has_builtin(__builtin_popcount)
       if (sizeof (T) <= sizeof (unsigned int))
         return __builtin_popcount (v);
    +#endif
     
    +#if hb_has_builtin(__builtin_popcountl)
       if (sizeof (T) <= sizeof (unsigned long))
         return __builtin_popcountl (v);
    +#endif
     
    +#if hb_has_builtin(__builtin_popcountll)
       if (sizeof (T) <= sizeof (unsigned long long))
         return __builtin_popcountll (v);
     #endif
    @@ -641,13 +647,17 @@
     {
       if (unlikely (!v)) return 0;
     
    -#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
    +#if hb_has_builtin(__builtin_clz)
       if (sizeof (T) <= sizeof (unsigned int))
         return sizeof (unsigned int) * 8 - __builtin_clz (v);
    +#endif
     
    +#if hb_has_builtin(__builtin_clzl)
       if (sizeof (T) <= sizeof (unsigned long))
         return sizeof (unsigned long) * 8 - __builtin_clzl (v);
    +#endif
     
    +#if hb_has_builtin(__builtin_clzll)
       if (sizeof (T) <= sizeof (unsigned long long))
         return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
     #endif
    @@ -715,13 +725,17 @@
     {
       if (unlikely (!v)) return 8 * sizeof (T);
     
    -#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
    +#if hb_has_builtin(__builtin_ctz)
       if (sizeof (T) <= sizeof (unsigned int))
         return __builtin_ctz (v);
    +#endif
     
    +#if hb_has_builtin(__builtin_ctzl)
       if (sizeof (T) <= sizeof (unsigned long))
         return __builtin_ctzl (v);
    +#endif
     
    +#if hb_has_builtin(__builtin_ctzll)
       if (sizeof (T) <= sizeof (unsigned long long))
         return __builtin_ctzll (v);
     #endif
    @@ -875,8 +889,7 @@
     static inline bool
     hb_unsigned_mul_overflows (unsigned int count, unsigned int size, unsigned *result = nullptr)
     {
    -/* avoid with xlc16 clang on AIX; it sets the gcc macros */
    -#if (defined(__GNUC__) && !defined(AIX) && (__GNUC__ >= 4)) || (defined(__clang__) && (__clang_major__ >= 8))
    +#if hb_has_builtin(__builtin_mul_overflow)
       unsigned stack_result;
       if (!result)
         result = &stack_result;
    @@ -1331,4 +1344,62 @@
     HB_FUNCOBJ (hb_dec);
     
     
    +/* Adapted from kurbo implementation with extra parameters added,
    + * and finding for a particular range instead of 0.
    + *
    + * For documentation and implementation see:
    + *
    + * [ITP method]: https://en.wikipedia.org/wiki/ITP_Method
    + * [An Enhancement of the Bisection Method Average Performance Preserving Minmax Optimality]: https://dl.acm.org/doi/10.1145/3423597
    + * https://docs.rs/kurbo/0.8.1/kurbo/common/fn.solve_itp.html
    + * https://github.com/linebender/kurbo/blob/fd839c25ea0c98576c7ce5789305822675a89938/src/common.rs#L162-L248
    + */
    +template 
    +double solve_itp (func_t f,
    +                  double a, double b,
    +                  double epsilon,
    +                  double min_y, double max_y,
    +                  double &ya, double &yb, double &y)
    +{
    +  unsigned n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0));
    +  const unsigned n0 = 1; // Hardwired
    +  const double k1 = 0.2 / (b - a); // Hardwired.
    +  unsigned nmax = n0 + n1_2;
    +  double scaled_epsilon = epsilon * double (1llu << nmax);
    +  double _2_epsilon = 2.0 * epsilon;
    +  while (b - a > _2_epsilon)
    +  {
    +    double x1_2 = 0.5 * (a + b);
    +    double r = scaled_epsilon - 0.5 * (b - a);
    +    double xf = (yb * a - ya * b) / (yb - ya);
    +    double sigma = x1_2 - xf;
    +    double b_a = b - a;
    +    // This has k2 = 2 hardwired for efficiency.
    +    double b_a_k2 = b_a * b_a;
    +    double delta = k1 * b_a_k2;
    +    int sigma_sign = sigma >= 0 ? +1 : -1;
    +    double xt = delta <= fabs (x1_2 - xf) ? xf + delta * sigma_sign : x1_2;
    +    double xitp = fabs (xt - x1_2) <= r ? xt : x1_2 - r * sigma_sign;
    +    double yitp = f (xitp);
    +    if (yitp > max_y)
    +    {
    +      b = xitp;
    +      yb = yitp;
    +    }
    +    else if (yitp < min_y)
    +    {
    +      a = xitp;
    +      ya = yitp;
    +    }
    +    else
    +    {
    +      y = yitp;
    +      return xitp;
    +    }
    +    scaled_epsilon *= 0.5;
    +  }
    +  return 0.5 * (a + b);
    +}
    +
    +
     #endif /* HB_ALGS_HH */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -83,9 +83,15 @@
     
       unsigned int get_population () const { return forw_map.get_population (); }
     
    +
       protected:
       hb_map_t  forw_map;
       hb_map_t  back_map;
    +
    +  public:
    +  auto keys () const HB_AUTO_RETURN (+ forw_map.keys())
    +  auto values () const HB_AUTO_RETURN (+ forw_map.values())
    +  auto iter () const HB_AUTO_RETURN (+ forw_map.iter())
     };
     
     /* Inremental bimap: only lhs is given, rhs is incrementally assigned */
    @@ -108,6 +114,9 @@
       hb_codepoint_t skip ()
       { return next_value++; }
     
    +  hb_codepoint_t skip (unsigned count)
    +  { return next_value += count; }
    +
       hb_codepoint_t get_next_value () const
       { return next_value; }
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -194,7 +194,7 @@
           unsigned int end = major_start (m + 1);
           do
           {
    -        if (v || page) /* The v check is to optimize out the page check if v is true. */
    +        if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
               page->set (g, v);
     
             array = &StructAtOffsetUnaligned (array, stride);
    @@ -238,7 +238,7 @@
             if (g < last_g) return false;
             last_g = g;
     
    -        if (v || page) /* The v check is to optimize out the page check if v is true. */
    +        if (g != INVALID && (v || page)) /* The v check is to optimize out the page check if v is true. */
               page->add (g);
     
             array = &StructAtOffsetUnaligned (array, stride);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-blob.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-blob.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-blob.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-blob.h	2023-10-06 05:33:33.000000000 +0000
    @@ -63,7 +63,7 @@
      *   HarfBuzz and doing that just once (no reuse!),
      *
      * - If the font is mmap()ed, it's okay to use
    - *   @HB_MEMORY_READONLY_MAY_MAKE_WRITABLE, however, using that mode
    + *   @HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, however, using that mode
      *   correctly is very tricky.  Use @HB_MEMORY_MODE_READONLY instead.
      **/
     typedef enum {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -40,6 +40,11 @@
      * Buffers serve a dual role in HarfBuzz; before shaping, they hold
      * the input characters that are passed to hb_shape(), and after
      * shaping they hold the output glyphs.
    + *
    + * The input buffer is a sequence of Unicode codepoints, with
    + * associated attributes such as direction and script.  The output
    + * buffer is a sequence of glyphs, with associated attributes such
    + * as position and cluster.
      **/
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-cache.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-cache.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-cache.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-cache.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -30,7 +30,19 @@
     #include "hb.hh"
     
     
    -/* Implements a lockfree cache for int->int functions. */
    +/* Implements a lockfree cache for int->int functions.
    + *
    + * The cache is a fixed-size array of 16-bit or 32-bit integers.
    + * The key is split into two parts: the cache index and the rest.
    + *
    + * The cache index is used to index into the array.  The rest is used
    + * to store the key and the value.
    + *
    + * The value is stored in the least significant bits of the integer.
    + * The key is stored in the most significant bits of the integer.
    + * The key is shifted by cache_bits to the left to make room for the
    + * value.
    + */
     
     template Note: If the blob font format is not a collection, @index
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-face.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-face.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-face.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-face.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -76,7 +76,7 @@
         if (unlikely (!reference_table_func))
           return hb_blob_get_empty ();
     
    -    blob = reference_table_func (/*XXX*/const_cast (this), tag, user_data);
    +    blob = reference_table_func (/*Oh, well.*/const_cast (this), tag, user_data);
         if (unlikely (!blob))
           return hb_blob_get_empty ();
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-font.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-font.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-font.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-font.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -59,6 +59,11 @@
      *
      * HarfBuzz provides a built-in set of lightweight default
      * functions for each method in #hb_font_funcs_t.
    + *
    + * The default font functions are implemented in terms of the
    + * #hb_font_funcs_t methods of the parent font object.  This allows
    + * client programs to override only the methods they need to, and
    + * otherwise inherit the parent font's implementation, if any.
      **/
     
     
    @@ -1387,7 +1392,7 @@
     /**
      * hb_font_get_glyph_shape:
      * @font: #hb_font_t to work upon
    - * @glyph: : The glyph ID
    + * @glyph: The glyph ID
      * @dfuncs: #hb_draw_funcs_t to draw to
      * @draw_data: User data to pass to draw callbacks
      *
    @@ -1409,7 +1414,7 @@
     /**
      * hb_font_draw_glyph:
      * @font: #hb_font_t to work upon
    - * @glyph: : The glyph ID
    + * @glyph: The glyph ID
      * @dfuncs: #hb_draw_funcs_t to draw to
      * @draw_data: User data to pass to draw callbacks
      *
    @@ -2650,6 +2655,79 @@
     }
     
     /**
    + * hb_font_set_variation:
    + * @font: #hb_font_t to work upon
    + * @tag: The #hb_tag_t tag of the variation-axis name
    + * @value: The value of the variation axis
    + *
    + * Change the value of one variation axis on the font.
    + *
    + * Note: This function is expensive to be called repeatedly.
    + *   If you want to set multiple variation axes at the same time,
    + *   use hb_font_set_variations() instead.
    + *
    + * Since: 7.1.0
    + */
    +void
    +hb_font_set_variation (hb_font_t *font,
    +                       hb_tag_t tag,
    +                       float    value)
    +{
    +  if (hb_object_is_immutable (font))
    +    return;
    +
    +  font->serial_coords = ++font->serial;
    +
    +  // TODO Share some of this code with set_variations()
    +
    +  const OT::fvar &fvar = *font->face->table.fvar;
    +  auto axes = fvar.get_axes ();
    +  const unsigned coords_length = axes.length;
    +
    +  int *normalized = coords_length ? (int *) hb_calloc (coords_length, sizeof (int)) : nullptr;
    +  float *design_coords = coords_length ? (float *) hb_calloc (coords_length, sizeof (float)) : nullptr;
    +
    +  if (unlikely (coords_length && !(normalized && design_coords)))
    +  {
    +    hb_free (normalized);
    +    hb_free (design_coords);
    +    return;
    +  }
    +
    +  /* Initialize design coords. */
    +  if (font->design_coords)
    +  {
    +    assert (coords_length == font->num_coords);
    +    for (unsigned int i = 0; i < coords_length; i++)
    +      design_coords[i] = font->design_coords[i];
    +  }
    +  else
    +  {
    +    for (unsigned int i = 0; i < coords_length; i++)
    +      design_coords[i] = axes[i].get_default ();
    +    if (font->instance_index != HB_FONT_NO_VAR_NAMED_INSTANCE)
    +    {
    +      unsigned count = coords_length;
    +      /* This may fail if index is out-of-range;
    +       * That's why we initialize design_coords from fvar above
    +       * unconditionally. */
    +      hb_ot_var_named_instance_get_design_coords (font->face, font->instance_index,
    +                                                  &count, design_coords);
    +    }
    +  }
    +
    +  for (unsigned axis_index = 0; axis_index < coords_length; axis_index++)
    +    if (axes[axis_index].axisTag == tag)
    +      design_coords[axis_index] = value;
    +
    +  font->face->table.avar->map_coords (normalized, coords_length);
    +
    +  hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
    +  _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
    +
    +}
    +
    +/**
      * hb_font_set_var_coords_design:
      * @font: #hb_font_t to work upon
      * @coords: (array length=coords_length): Array of variation coordinates to apply
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-font.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-font.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-font.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-font.h	2023-10-06 05:33:33.000000000 +0000
    @@ -1151,6 +1151,11 @@
                             unsigned int variations_length);
     
     HB_EXTERN void
    +hb_font_set_variation (hb_font_t *font,
    +                       hb_tag_t tag,
    +                       float    value);
    +
    +HB_EXTERN void
     hb_font_set_var_coords_design (hb_font_t *font,
                                    const float *coords,
                                    unsigned int coords_length);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ft.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ft.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ft.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ft.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -85,7 +85,7 @@
      */
     
     
    -using hb_ft_advance_cache_t = hb_cache_t<16, 8, 8, false>;
    +using hb_ft_advance_cache_t = hb_cache_t<16, 24, 8, false>;
     
     struct hb_ft_font_t
     {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -246,7 +246,15 @@
      * Compiler attributes
      */
     
    -#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
    +// gcc 10 has __has_builtin but not earlier versions. Sanction any gcc >= 5
    +// clang defines it so no need.
    +#ifdef __has_builtin
    +#define hb_has_builtin __has_builtin
    +#else
    +#define hb_has_builtin(x) ((defined(__GNUC__) && __GNUC__ >= 5))
    +#endif
    +
    +#if defined(__OPTIMIZE__) && hb_has_builtin(__builtin_expect)
     #define likely(expr) (__builtin_expect (!!(expr), 1))
     #define unlikely(expr) (__builtin_expect (!!(expr), 0))
     #else
    @@ -501,6 +509,12 @@
     static_assert ((sizeof (hb_var_int_t) == 4), "");
     
     
    +/* Pie time. */
    +// https://github.com/harfbuzz/harfbuzz/issues/4166
    +#define HB_PI 3.14159265358979f
    +#define HB_2_PI (2.f * HB_PI)
    +
    +
     /* Headers we include for everyone.  Keep topologically sorted by dependency.
      * They express dependency amongst themselves, but no other file should include
      * them directly.*/
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-map.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-map.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-map.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-map.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -399,7 +399,7 @@
     hb_map_keys (const hb_map_t *map,
                  hb_set_t *keys)
     {
    -  map->keys (*keys);
    +  hb_copy (map->keys() , *keys);
     }
     
     /**
    @@ -415,5 +415,5 @@
     hb_map_values (const hb_map_t *map,
                    hb_set_t *values)
     {
    -  map->values (*values);
    +  hb_copy (map->values() , *values);
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-map.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-map.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-map.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-map.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -317,16 +317,6 @@
         hb_copy (other, *this);
       }
     
    -  void keys (hb_set_t &keys_) const
    -  {
    -    hb_copy (keys() , keys_);
    -  }
    -
    -  void values (hb_set_t &values_) const
    -  {
    -    hb_copy (values() , values_);
    -  }
    -
       /*
        * Iterator
        */
    @@ -353,7 +343,8 @@
       )
       auto keys () const HB_AUTO_RETURN
       (
    -    + keys_ref ()
    +    + iter_items ()
    +    | hb_map (&item_t::key)
         | hb_map (hb_ridentity)
       )
       auto values_ref () const HB_AUTO_RETURN
    @@ -363,7 +354,8 @@
       )
       auto values () const HB_AUTO_RETURN
       (
    -    + values_ref ()
    +    + iter_items ()
    +    | hb_map (&item_t::value)
         | hb_map (hb_ridentity)
       )
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -404,7 +404,7 @@
                      unsigned distance) const
             {
               if (k > last) return +1;
    -          if (k < (&last)[distance]) return -1;
    +          if (k < (&last)[distance]/*first*/) return -1;
               return 0;
             }
             HBUINT16 last;
    @@ -413,7 +413,7 @@
           const HBUINT16 *found = hb_bsearch (codepoint,
                                               this->endCount,
                                               this->segCount,
    -                                          2,
    +                                          sizeof (CustomRange),
                                               _hb_cmp_method,
                                               this->segCount + 1);
           if (unlikely (!found))
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-face-table-list.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -93,6 +93,7 @@
     #ifndef HB_NO_VAR
     HB_OT_CORE_TABLE (OT, fvar)
     HB_OT_CORE_TABLE (OT, avar)
    +HB_OT_CORE_TABLE (OT, cvar)
     HB_OT_ACCELERATOR (OT, gvar)
     HB_OT_CORE_TABLE (OT, MVAR)
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -413,7 +413,7 @@
       if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
       if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
     #endif
    -#if !defined(HB_NO_COLOR)
    +#if !defined(HB_NO_COLOR) && !defined(HB_NO_PAINT)
       if (ot_face->COLR->get_extents (font, glyph, extents)) return true;
     #endif
       if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
    @@ -633,20 +633,4 @@
                          _hb_ot_font_destroy);
     }
     
    -#ifndef HB_NO_VAR
    -bool
    -_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical,
    -                                             int *lsb)
    -{
    -  return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb);
    -}
    -
    -unsigned
    -_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
    -{
    -  return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
    -}
    -#endif
    -
    -
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -76,7 +76,7 @@
       HBUINT8                       maxWidth;       /* Maximum width. */
       UnsizedArrayOf       widthsZ;        /* Array of widths (numGlyphs is from the 'maxp' table). */
       public:
    -  DEFINE_SIZE_ARRAY (2, widthsZ);
    +  DEFINE_SIZE_UNBOUNDED (2);
     };
     
     
    @@ -87,14 +87,6 @@
       unsigned int get_size () const
       { return min_size + numRecords * sizeDeviceRecord; }
     
    -  const DeviceRecord& operator [] (unsigned int i) const
    -  {
    -    /* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed.
    -     * https://github.com/harfbuzz/harfbuzz/issues/1300 */
    -    if (unlikely (i >= numRecords)) return Null (DeviceRecord);
    -    return StructAtOffset (&this->firstDeviceRecord, i * sizeDeviceRecord);
    -  }
    -
       template
       bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-head-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -63,7 +63,25 @@
       bool subset (hb_subset_context_t *c) const
       {
         TRACE_SUBSET (this);
    -    return_trace (serialize (c->serializer));
    +    head *out = c->serializer->embed (this);
    +    if (unlikely (!out)) return_trace (false);
    +
    +    if (c->plan->normalized_coords)
    +    {
    +      if (unlikely (!c->serializer->check_assign (out->xMin, c->plan->head_maxp_info.xMin,
    +                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
    +        return_trace (false);
    +      if (unlikely (!c->serializer->check_assign (out->xMax, c->plan->head_maxp_info.xMax,
    +                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
    +        return_trace (false);
    +      if (unlikely (!c->serializer->check_assign (out->yMin, c->plan->head_maxp_info.yMin,
    +                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
    +        return_trace (false);
    +      if (unlikely (!c->serializer->check_assign (out->yMax, c->plan->head_maxp_info.yMax,
    +                                                  HB_SERIALIZE_ERROR_INT_OVERFLOW)))
    +        return_trace (false);
    +    }
    +    return_trace (true);
       }
     
       enum mac_style_flag_t {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -50,6 +50,9 @@
     HB_INTERNAL unsigned
     _glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
     
    +HB_INTERNAL bool
    +_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb);
    +
     
     namespace OT {
     
    @@ -92,7 +95,7 @@
     
         unsigned int length;
         H *table = (H *) hb_blob_get_data (dest_blob, &length);
    -    table->numberOfLongMetrics = num_hmetrics;
    +    c->serializer->check_assign (table->numberOfLongMetrics, num_hmetrics, HB_SERIALIZE_ERROR_INT_OVERFLOW);
     
     #ifndef HB_NO_VAR
         if (c->plan->normalized_coords)
    @@ -165,12 +168,19 @@
             lm.sb = _.second;
             if (unlikely (!c->embed (&lm))) return;
           }
    -      else
    +      else if (idx < 0x10000u)
           {
             FWORD *sb = c->allocate_size (FWORD::static_size);
             if (unlikely (!sb)) return;
             *sb = _.second;
           }
    +      else
    +      {
    +        // TODO: This does not do tail optimization.
    +        UFWORD *adv = c->allocate_size (UFWORD::static_size);
    +        if (unlikely (!adv)) return;
    +        *adv = _.first;
    +      }
           idx++;
         }
       }
    @@ -189,7 +199,7 @@
           /* Determine num_long_metrics to encode. */
           auto& plan = c->plan;
     
    -      num_long_metrics = plan->num_output_glyphs ();
    +      num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu);
           unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
           while (num_long_metrics > 1 &&
                  last_advance == get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 2, _mtx))
    @@ -208,7 +218,8 @@
                       if (!c->plan->old_gid_for_new_gid (_, &old_gid))
                         return hb_pair (0u, 0);
                       int lsb = 0;
    -                  (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb);
    +                  if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
    +                    (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb);
                       return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
                     }
                     return mtx_map->get (_);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -64,6 +64,8 @@
      * @include: hb-ot.h
      *
      * Functions for querying OpenType Layout features in the font face.
    + * See the OpenType
    + * specification for details.
      **/
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -529,6 +529,9 @@
           return_trace (true);
       }
     
    +  void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
    +  { nameids_to_retain->add (subfamilyNameID); }
    +
       bool subset (hb_subset_context_t *c) const
       {
         TRACE_SUBSET (this);
    @@ -585,6 +588,9 @@
         return_trace (c->check_struct (this));
       }
     
    +  void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
    +  { nameids_to_retain->add (uiNameID); }
    +
       bool subset (hb_subset_context_t *c) const
       {
         TRACE_SUBSET (this);
    @@ -632,6 +638,20 @@
       unsigned get_size () const
       { return min_size + characters.len * HBUINT24::static_size; }
     
    +  void collect_name_ids (hb_set_t *nameids_to_retain /* OUT */) const
    +  {
    +    if (featUILableNameID) nameids_to_retain->add (featUILableNameID);
    +    if (featUITooltipTextNameID) nameids_to_retain->add (featUITooltipTextNameID);
    +    if (sampleTextNameID) nameids_to_retain->add (sampleTextNameID);
    +
    +    if (!firstParamUILabelNameID || !numNamedParameters || numNamedParameters >= 0x7FFF)
    +      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);
    +  }
    +
       bool subset (hb_subset_context_t *c) const
       {
         TRACE_SUBSET (this);
    @@ -694,6 +714,19 @@
         return_trace (true);
       }
     
    +  void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const
    +  {
    +#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
    +    return;
    +#endif
    +    if (tag == HB_TAG ('s','i','z','e'))
    +      return (u.size.collect_name_ids (nameids_to_retain));
    +    if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
    +      return (u.stylisticSet.collect_name_ids (nameids_to_retain));
    +    if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
    +      return (u.characterVariants.collect_name_ids (nameids_to_retain));
    +  }
    +
       bool subset (hb_subset_context_t *c, const Tag* tag) const
       {
         TRACE_SUBSET (this);
    @@ -762,6 +795,12 @@
       bool intersects_lookup_indexes (const hb_map_t *lookup_indexes) const
       { return lookupIndex.intersects (lookup_indexes); }
     
    +  void collect_name_ids (hb_tag_t tag, hb_set_t *nameids_to_retain /* OUT */) const
    +  {
    +    if (featureParams)
    +      get_feature_params ().collect_name_ids (tag, nameids_to_retain);
    +  }
    +
       bool subset (hb_subset_context_t         *c,
                    hb_subset_layout_context_t  *l,
                    const Tag                   *tag = nullptr) const
    @@ -2233,19 +2272,20 @@
     {
       float evaluate (int coord) const
       {
    -    int start = startCoord.to_int (), peak = peakCoord.to_int (), end = endCoord.to_int ();
    +    int peak = peakCoord.to_int ();
    +    if (peak == 0 || coord == peak)
    +      return 1.f;
    +
    +    int start = startCoord.to_int (), end = endCoord.to_int ();
     
         /* TODO Move these to sanitize(). */
         if (unlikely (start > peak || peak > end))
    -      return 1.;
    +      return 1.f;
         if (unlikely (start < 0 && end > 0 && peak != 0))
    -      return 1.;
    -
    -    if (peak == 0 || coord == peak)
    -      return 1.;
    +      return 1.f;
     
         if (coord <= start || end <= coord)
    -      return 0.;
    +      return 0.f;
     
         /* Interpolate */
         if (coord < peak)
    @@ -2462,10 +2502,9 @@
         {
           for (r = 0; r < src_word_count; r++)
           {
    -        for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
    +        for (unsigned old_gid : inner_map.keys())
             {
    -          unsigned int old = inner_map.backward (i);
    -          int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
    +          int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size);
               if (delta < -65536 || 65535 < delta)
               {
                 has_long = true;
    @@ -2482,10 +2521,9 @@
           bool short_circuit = src_long_words == has_long && src_word_count <= r;
     
           delta_sz[r] = kZero;
    -      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
    +      for (unsigned old_gid : inner_map.keys())
           {
    -        unsigned int old = inner_map.backward (i);
    -        int32_t delta = src->get_item_delta_fast (old, r, src_delta_bytes, src_row_size);
    +        int32_t delta = src->get_item_delta_fast (old_gid, r, src_delta_bytes, src_row_size);
             if (delta < min_threshold || max_threshold < delta)
             {
               delta_sz[r] = kWord;
    @@ -2546,8 +2584,8 @@
         {
           unsigned int region = regionIndices.arrayZ[r];
           if (region_indices.has (region)) continue;
    -      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
    -        if (get_item_delta_fast (inner_map.backward (i), r, delta_bytes, row_size) != 0)
    +      for (hb_codepoint_t old_gid : inner_map.keys())
    +        if (get_item_delta_fast (old_gid, r, delta_bytes, row_size) != 0)
             {
               region_indices.add (region);
               break;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -487,7 +487,8 @@
           /* Ignore ZWJ if we are matching context, or asked to. */
           matcher.set_ignore_zwj  (context_match || c->auto_zwj);
           matcher.set_mask (context_match ? -1 : c->lookup_mask);
    -      matcher.set_per_syllable (c->per_syllable);
    +      /* Per syllable matching is only for GSUB. */
    +      matcher.set_per_syllable (c->table_index == 0 && c->per_syllable);
         }
         void set_lookup_props (unsigned int lookup_props)
         {
    @@ -4461,6 +4462,18 @@
         }
       }
     
    +  void collect_name_ids (const hb_map_t *feature_index_map,
    +                         hb_set_t *nameids_to_retain /* OUT */) const
    +  {
    +    unsigned count = get_feature_count ();
    +    for (unsigned i = 0 ; i < count; i++)
    +    {
    +      if (!feature_index_map->has (i)) continue;
    +      hb_tag_t tag = get_feature_tag (i);
    +      get_feature (i).collect_name_ids (tag, nameids_to_retain);
    +    }
    +  }
    +
       template 
       struct accelerator_t
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-maxp-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -100,7 +100,7 @@
         maxp *maxp_prime = c->serializer->embed (this);
         if (unlikely (!maxp_prime)) return_trace (false);
     
    -    maxp_prime->numGlyphs = c->plan->num_output_glyphs ();
    +    maxp_prime->numGlyphs = hb_min (c->plan->num_output_glyphs (), 0xFFFFu);
         if (maxp_prime->version.major == 1)
         {
           const maxpV1Tail *src_v1 = &StructAfter (*this);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-name.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-name.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-name.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-name.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -181,6 +181,4 @@
       return hb_ot_name_get_utf (face, name_id, language, text_size, text);
     }
     
    -#include "hb-ot-name-language-static.hh"
    -
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -99,6 +99,10 @@
         post *post_prime = c->serializer->start_embed ();
         if (unlikely (!post_prime)) return_trace (false);
     
    +    bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
    +    if (!serialize (c->serializer, glyph_names))
    +      return_trace (false);
    +
     #ifndef HB_NO_VAR
         if (c->plan->normalized_coords)
         {
    @@ -110,10 +114,6 @@
         }
     #endif
     
    -    bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
    -    if (!serialize (c->serializer, glyph_names))
    -      return_trace (false);
    -
         if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) &&
             !c->plan->pinned_at_default)
         {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -1067,12 +1067,15 @@
                   base = i;
                   while (base < end && is_halant (info[base]))
                     base++;
    -              info[base].indic_position() = POS_BASE_C;
    +              if (base < end)
    +                info[base].indic_position() = POS_BASE_C;
     
                   try_pref = false;
                 }
                 break;
               }
    +        if (base == end)
    +          break;
           }
           /* For Malayalam, skip over unformed below- (but NOT post-) forms. */
           if (buffer->props.script == HB_SCRIPT_MALAYALAM)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -536,6 +536,8 @@
         | hb_map (&AxisValue::get_value_name_id)
         | hb_sink (nameids_to_retain)
         ;
    +
    +    nameids_to_retain->add (elidedFallbackNameID);
       }
     
       bool subset (hb_subset_context_t *c) const
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -222,21 +222,371 @@
     
     struct VarStoreInstancer
     {
    -  VarStoreInstancer (const VariationStore &varStore,
    -                     const DeltaSetIndexMap &varIdxMap,
    +  VarStoreInstancer (const VariationStore *varStore,
    +                     const DeltaSetIndexMap *varIdxMap,
                          hb_array_t coords) :
         varStore (varStore), varIdxMap (varIdxMap), coords (coords) {}
     
    -  operator bool () const { return bool (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 varStore.get_delta (varIdxMap.map (VarIdx::add (varIdx, offset)), coords); }
    +  { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); }
     
    -  const VariationStore &varStore;
    -  const DeltaSetIndexMap &varIdxMap;
    +  const VariationStore *varStore;
    +  const DeltaSetIndexMap *varIdxMap;
       hb_array_t coords;
     };
     
    +/* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */
    +struct TupleVariationHeader
    +{
    +  unsigned get_size (unsigned axis_count) const
    +  { return min_size + get_all_tuples (axis_count).get_size (); }
    +
    +  unsigned get_data_size () const { return varDataSize; }
    +
    +  const TupleVariationHeader &get_next (unsigned axis_count) const
    +  { return StructAtOffset (this, get_size (axis_count)); }
    +
    +  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
    +  {
    +    const F2DOT14 *peak_tuple;
    +
    +    unsigned start_idx = 0;
    +    unsigned end_idx = coord_count;
    +
    +    if (has_peak ())
    +      peak_tuple = get_peak_tuple (coord_count).arrayZ;
    +    else
    +    {
    +      unsigned int index = get_index ();
    +      if (unlikely ((index + 1) * coord_count > shared_tuples.length))
    +        return 0.f;
    +      peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count).arrayZ;
    +
    +      if (shared_tuple_active_idx)
    +      {
    +        assert (index < shared_tuple_active_idx->length);
    +        int v = (*shared_tuple_active_idx).arrayZ[index];
    +        if (v != -1)
    +        {
    +          start_idx = v;
    +          end_idx = start_idx + 1;
    +        }
    +      }
    +    }
    +
    +    const F2DOT14 *start_tuple = nullptr;
    +    const F2DOT14 *end_tuple = nullptr;
    +    bool has_interm = has_intermediate ();
    +    if (has_interm)
    +    {
    +      start_tuple = get_start_tuple (coord_count).arrayZ;
    +      end_tuple = get_end_tuple (coord_count).arrayZ;
    +    }
    +
    +    float scalar = 1.f;
    +    for (unsigned int i = start_idx; i < end_idx; i++)
    +    {
    +      int peak = peak_tuple[i].to_int ();
    +      if (!peak) continue;
    +
    +      int v = coords[i];
    +      if (v == peak) continue;
    +
    +      if (has_interm)
    +      {
    +        int start = start_tuple[i].to_int ();
    +        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 < peak)
    +        { if (peak != start) scalar *= (float) (v - start) / (peak - start); }
    +        else
    +        { if (peak != end) scalar *= (float) (end - v) / (end - peak); }
    +      }
    +      else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f;
    +      else
    +        scalar *= (float) v / peak;
    +    }
    +    return scalar;
    +  }
    +
    +  bool           has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; }
    +  bool   has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; }
    +  bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; }
    +  unsigned      get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; }
    +
    +  protected:
    +  struct TuppleIndex : HBUINT16
    +  {
    +    enum Flags {
    +      EmbeddedPeakTuple   = 0x8000u,
    +      IntermediateRegion  = 0x4000u,
    +      PrivatePointNumbers = 0x2000u,
    +      TupleIndexMask      = 0x0FFFu
    +    };
    +
    +    DEFINE_SIZE_STATIC (2);
    +  };
    +
    +  hb_array_t get_all_tuples (unsigned axis_count) const
    +  { return StructAfter> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); }
    +  hb_array_t get_peak_tuple (unsigned axis_count) const
    +  { return get_all_tuples (axis_count).sub_array (0, axis_count); }
    +  hb_array_t get_start_tuple (unsigned axis_count) const
    +  { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); }
    +  hb_array_t get_end_tuple (unsigned axis_count) const
    +  { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); }
    +
    +  HBUINT16      varDataSize;    /* The size in bytes of the serialized
    +                                 * data for this tuple variation table. */
    +  TuppleIndex   tupleIndex;     /* A packed field. The high 4 bits are flags (see below).
    +                                   The low 12 bits are an index into a shared tuple
    +                                   records array. */
    +  /* UnsizedArrayOf peakTuple - optional */
    +                                /* Peak tuple record for this tuple variation table — optional,
    +                                 * determined by flags in the tupleIndex value.
    +                                 *
    +                                 * Note that this must always be included in the 'cvar' table. */
    +  /* UnsizedArrayOf intermediateStartTuple - optional */
    +                                /* Intermediate start tuple record for this tuple variation table — optional,
    +                                   determined by flags in the tupleIndex value. */
    +  /* UnsizedArrayOf intermediateEndTuple - optional */
    +                                /* Intermediate end tuple record for this tuple variation table — optional,
    +                                 * determined by flags in the tupleIndex value. */
    +  public:
    +  DEFINE_SIZE_MIN (4);
    +};
    +
    +struct TupleVariationData
    +{
    +  bool sanitize (hb_sanitize_context_t *c) const
    +  {
    +    TRACE_SANITIZE (this);
    +    // here check on min_size only, TupleVariationHeader and var data will be
    +    // checked while accessing through iterator.
    +    return_trace (c->check_struct (this));
    +  }
    +
    +  unsigned get_size (unsigned axis_count) const
    +  {
    +    unsigned total_size = min_size;
    +    unsigned count = tupleVarCount;
    +    const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header());
    +    for (unsigned i = 0; i < count; i++)
    +    {
    +      total_size += tuple_var_header->get_size (axis_count) + tuple_var_header->get_data_size ();
    +      tuple_var_header = &tuple_var_header->get_next (axis_count);
    +    }
    +
    +    return total_size;
    +  }
    +
    +  const TupleVariationHeader &get_tuple_var_header (void) const
    +  { return StructAfter (data); }
    +
    +  struct tuple_iterator_t
    +  {
    +    void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_, const void *table_base_)
    +    {
    +      var_data_bytes = var_data_bytes_;
    +      var_data = var_data_bytes_.as ();
    +      index = 0;
    +      axis_count = axis_count_;
    +      current_tuple = &var_data->get_tuple_var_header ();
    +      data_offset = 0;
    +      table_base = table_base_;
    +    }
    +
    +    bool get_shared_indices (hb_vector_t &shared_indices /* OUT */)
    +    {
    +      if (var_data->has_shared_point_numbers ())
    +      {
    +        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;
    +        data_offset = p - base;
    +      }
    +      return true;
    +    }
    +
    +    bool is_valid () const
    +    {
    +      return (index < var_data->tupleVarCount.get_count ()) &&
    +             var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) &&
    +             var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (),
    +                                                                current_tuple->get_size (axis_count)));
    +    }
    +
    +    bool move_to_next ()
    +    {
    +      data_offset += current_tuple->get_data_size ();
    +      current_tuple = ¤t_tuple->get_next (axis_count);
    +      index++;
    +      return is_valid ();
    +    }
    +
    +    const HBUINT8 *get_serialized_data () const
    +    { return &(table_base+var_data->data) + data_offset; }
    +
    +    private:
    +    const TupleVariationData *var_data;
    +    unsigned int index;
    +    unsigned int axis_count;
    +    unsigned int data_offset;
    +    const void *table_base;
    +
    +    public:
    +    hb_bytes_t var_data_bytes;
    +    const TupleVariationHeader *current_tuple;
    +  };
    +
    +  static bool get_tuple_iterator (hb_bytes_t var_data_bytes, unsigned axis_count,
    +                                  const void *table_base,
    +                                  hb_vector_t &shared_indices /* OUT */,
    +                                  tuple_iterator_t *iterator /* OUT */)
    +  {
    +    iterator->init (var_data_bytes, axis_count, table_base);
    +    if (!iterator->get_shared_indices (shared_indices))
    +      return false;
    +    return iterator->is_valid ();
    +  }
    +
    +  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)
    +  {
    +    enum packed_point_flag_t
    +    {
    +      POINTS_ARE_WORDS     = 0x80,
    +      POINT_RUN_COUNT_MASK = 0x7F
    +    };
    +
    +    if (unlikely (p + 1 > end)) return false;
    +
    +    unsigned count = *p++;
    +    if (count & POINTS_ARE_WORDS)
    +    {
    +      if (unlikely (p + 1 > end)) return false;
    +      count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
    +    }
    +    if (unlikely (!points.resize (count, false))) return false;
    +
    +    unsigned n = 0;
    +    unsigned i = 0;
    +    while (i < count)
    +    {
    +      if (unlikely (p + 1 > end)) return false;
    +      unsigned control = *p++;
    +      unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1;
    +      unsigned stop = i + run_count;
    +      if (unlikely (stop > count)) return false;
    +      if (control & POINTS_ARE_WORDS)
    +      {
    +        if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
    +        for (; i < stop; i++)
    +        {
    +          n += *(const HBUINT16 *)p;
    +          points.arrayZ[i] = n;
    +          p += HBUINT16::static_size;
    +        }
    +      }
    +      else
    +      {
    +        if (unlikely (p + run_count > end)) return false;
    +        for (; i < stop; i++)
    +        {
    +          n += *p++;
    +          points.arrayZ[i] = n;
    +        }
    +      }
    +    }
    +    return true;
    +  }
    +
    +  static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
    +                             hb_vector_t &deltas /* IN/OUT */,
    +                             const HBUINT8 *end)
    +  {
    +    enum packed_delta_flag_t
    +    {
    +      DELTAS_ARE_ZERO      = 0x80,
    +      DELTAS_ARE_WORDS     = 0x40,
    +      DELTA_RUN_COUNT_MASK = 0x3F
    +    };
    +
    +    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;
    +  }
    +
    +  bool has_data () const { return tupleVarCount; }
    +
    +  protected:
    +  struct TupleVarCount : HBUINT16
    +  {
    +    bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
    +    unsigned int get_count () const { return (*this) & CountMask; }
    +
    +    protected:
    +    enum Flags
    +    {
    +      SharedPointNumbers= 0x8000u,
    +      CountMask         = 0x0FFFu
    +    };
    +    public:
    +    DEFINE_SIZE_STATIC (2);
    +  };
    +
    +  TupleVarCount tupleVarCount;  /* A packed field. The high 4 bits are flags, and the
    +                                 * 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
    +                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);
    +};
     
     } /* namespace OT */
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -0,0 +1,158 @@
    +/*
    + * Copyright © 2023  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_OT_VAR_CVAR_TABLE_HH
    +#define HB_OT_VAR_CVAR_TABLE_HH
    +
    +#include "hb-ot-var-common.hh"
    +
    +
    +namespace OT {
    +/*
    + * cvar -- control value table (CVT) Variations
    + * https://docs.microsoft.com/en-us/typography/opentype/spec/cvar
    + */
    +#define HB_OT_TAG_cvar HB_TAG('c','v','a','r')
    +
    +struct cvar
    +{
    +  static constexpr hb_tag_t tableTag = HB_OT_TAG_cvar;
    +
    +  bool sanitize (hb_sanitize_context_t *c) const
    +  {
    +    TRACE_SANITIZE (this);
    +    return_trace (c->check_struct (this) &&
    +                  version.sanitize (c) && likely (version.major == 1) &&
    +                  tupleVariationData.sanitize (c));
    +  }
    +
    +  const TupleVariationData* get_tuple_var_data (void) const
    +  { return &tupleVariationData; }
    +
    +  static bool calculate_cvt_deltas (unsigned axis_count,
    +                                    hb_array_t coords,
    +                                    unsigned num_cvt_item,
    +                                    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;
    +    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,
    +                                                 shared_indices, &iterator))
    +      return true; /* isn't applied at all */
    +
    +    hb_array_t shared_tuples = hb_array ();
    +    hb_vector_t private_indices;
    +    hb_vector_t unpacked_deltas;
    +
    +    do
    +    {
    +      float scalar = iterator.current_tuple->calculate_scalar (coords, axis_count, shared_tuples);
    +      if (scalar == 0.f) continue;
    +      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)))
    +        return false;
    +
    +      const HBUINT8 *end = p + length;
    +
    +      bool has_private_points = iterator.current_tuple->has_private_points ();
    +      if (has_private_points &&
    +          !TupleVariationData::unpack_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;
    +
    +      for (unsigned int i = 0; i < num_deltas; i++)
    +      {
    +        unsigned int idx = apply_to_all ? i : indices[i];
    +        if (unlikely (idx >= num_cvt_item)) continue;
    +        if (scalar != 1.0f) cvt_deltas[idx] += unpacked_deltas[i] * scalar ;
    +        else cvt_deltas[idx] += unpacked_deltas[i];
    +      }
    +    } while (iterator.move_to_next ());
    +
    +    return true;
    +  }
    +
    +  static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan,
    +                                        const TupleVariationData *tuple_var_data,
    +                                        const void *base)
    +  {
    +    const hb_tag_t cvt = HB_TAG('c','v','t',' ');
    +    hb_blob_t *cvt_blob = hb_face_reference_table (plan->source, cvt);
    +    hb_blob_t *cvt_prime_blob = hb_blob_copy_writable_or_fail (cvt_blob);
    +    hb_blob_destroy (cvt_blob);
    +
    +    if (unlikely (!cvt_prime_blob))
    +      return false;
    +
    +    unsigned cvt_blob_length = hb_blob_get_length (cvt_prime_blob);
    +    unsigned num_cvt_item = cvt_blob_length / FWORD::static_size;
    +
    +    hb_vector_t cvt_deltas;
    +    if (unlikely (!cvt_deltas.resize (num_cvt_item)))
    +    {
    +      hb_blob_destroy (cvt_prime_blob);
    +      return false;
    +    }
    +    hb_memset (cvt_deltas.arrayZ, 0, cvt_deltas.get_size ());
    +
    +    if (!calculate_cvt_deltas (plan->normalized_coords.length, plan->normalized_coords.as_array (),
    +                               num_cvt_item, tuple_var_data, base, cvt_deltas))
    +    {
    +      hb_blob_destroy (cvt_prime_blob);
    +      return false;
    +    }
    +
    +    FWORD *cvt_prime = (FWORD *) hb_blob_get_data_writable (cvt_prime_blob, nullptr);
    +    for (unsigned i = 0; i < num_cvt_item; i++)
    +      cvt_prime[i] += (int) roundf (cvt_deltas[i]);
    +
    +    bool success = plan->add_table (cvt, cvt_prime_blob);
    +    hb_blob_destroy (cvt_prime_blob);
    +    return success;
    +  }
    +
    +  protected:
    +  FixedVersion<>version;                /* Version of the CVT variation table
    +                                         * initially set to 0x00010000u */
    +  TupleVariationData tupleVariationData; /* TupleVariationDate for cvar table */
    +  public:
    +  DEFINE_SIZE_MIN (8);
    +};
    +
    +} /* namespace OT */
    +
    +
    +#endif /* HB_OT_VAR_CVAR_TABLE_HH */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -29,6 +29,7 @@
     #define HB_OT_VAR_GVAR_TABLE_HH
     
     #include "hb-open-type.hh"
    +#include "hb-ot-var-common.hh"
     
     /*
      * gvar -- Glyph Variation Table
    @@ -90,311 +91,8 @@
       }
     };
     
    -/* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */
    -struct TupleVariationHeader
    -{
    -  unsigned get_size (unsigned axis_count) const
    -  { return min_size + get_all_tuples (axis_count).get_size (); }
    -
    -  unsigned get_data_size () const { return varDataSize; }
    -
    -  const TupleVariationHeader &get_next (unsigned axis_count) const
    -  { return StructAtOffset (this, get_size (axis_count)); }
    -
    -  float calculate_scalar (hb_array_t coords, unsigned int coord_count,
    -                          const hb_array_t shared_tuples) const
    -  {
    -    hb_array_t peak_tuple;
    -
    -    if (has_peak ())
    -      peak_tuple = get_peak_tuple (coord_count);
    -    else
    -    {
    -      unsigned int index = get_index ();
    -      if (unlikely (index * coord_count >= shared_tuples.length))
    -        return 0.f;
    -      peak_tuple = shared_tuples.sub_array (coord_count * index, coord_count);
    -    }
    -
    -    hb_array_t start_tuple;
    -    hb_array_t end_tuple;
    -    if (has_intermediate ())
    -    {
    -      start_tuple = get_start_tuple (coord_count);
    -      end_tuple = get_end_tuple (coord_count);
    -    }
    -
    -    float scalar = 1.f;
    -    for (unsigned int i = 0; i < coord_count; i++)
    -    {
    -      int v = coords[i];
    -      int peak = peak_tuple[i].to_int ();
    -      if (!peak || v == peak) continue;
    -
    -      if (has_intermediate ())
    -      {
    -        int start = start_tuple[i].to_int ();
    -        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 < peak)
    -        { if (peak != start) scalar *= (float) (v - start) / (peak - start); }
    -        else
    -        { if (peak != end) scalar *= (float) (end - v) / (end - peak); }
    -      }
    -      else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f;
    -      else
    -        scalar *= (float) v / peak;
    -    }
    -    return scalar;
    -  }
    -
    -  bool           has_peak () const { return tupleIndex & TuppleIndex::EmbeddedPeakTuple; }
    -  bool   has_intermediate () const { return tupleIndex & TuppleIndex::IntermediateRegion; }
    -  bool has_private_points () const { return tupleIndex & TuppleIndex::PrivatePointNumbers; }
    -  unsigned      get_index () const { return tupleIndex & TuppleIndex::TupleIndexMask; }
    -
    -  protected:
    -  struct TuppleIndex : HBUINT16
    -  {
    -    enum Flags {
    -      EmbeddedPeakTuple   = 0x8000u,
    -      IntermediateRegion  = 0x4000u,
    -      PrivatePointNumbers = 0x2000u,
    -      TupleIndexMask      = 0x0FFFu
    -    };
    -
    -    DEFINE_SIZE_STATIC (2);
    -  };
    -
    -  hb_array_t get_all_tuples (unsigned axis_count) const
    -  { return StructAfter> (tupleIndex).as_array ((has_peak () + has_intermediate () * 2) * axis_count); }
    -  hb_array_t get_peak_tuple (unsigned axis_count) const
    -  { return get_all_tuples (axis_count).sub_array (0, axis_count); }
    -  hb_array_t get_start_tuple (unsigned axis_count) const
    -  { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count, axis_count); }
    -  hb_array_t get_end_tuple (unsigned axis_count) const
    -  { return get_all_tuples (axis_count).sub_array (has_peak () * axis_count + axis_count, axis_count); }
    -
    -  HBUINT16      varDataSize;    /* The size in bytes of the serialized
    -                                 * data for this tuple variation table. */
    -  TuppleIndex   tupleIndex;     /* A packed field. The high 4 bits are flags (see below).
    -                                   The low 12 bits are an index into a shared tuple
    -                                   records array. */
    -  /* UnsizedArrayOf peakTuple - optional */
    -                                /* Peak tuple record for this tuple variation table — optional,
    -                                 * determined by flags in the tupleIndex value.
    -                                 *
    -                                 * Note that this must always be included in the 'cvar' table. */
    -  /* UnsizedArrayOf intermediateStartTuple - optional */
    -                                /* Intermediate start tuple record for this tuple variation table — optional,
    -                                   determined by flags in the tupleIndex value. */
    -  /* UnsizedArrayOf intermediateEndTuple - optional */
    -                                /* Intermediate end tuple record for this tuple variation table — optional,
    -                                 * determined by flags in the tupleIndex value. */
    -  public:
    -  DEFINE_SIZE_MIN (4);
    -};
    -
    -struct GlyphVariationData
    -{
    -  const TupleVariationHeader &get_tuple_var_header (void) const
    -  { return StructAfter (data); }
    -
    -  struct tuple_iterator_t
    -  {
    -    void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_)
    -    {
    -      var_data_bytes = var_data_bytes_;
    -      var_data = var_data_bytes_.as ();
    -      index = 0;
    -      axis_count = axis_count_;
    -      current_tuple = &var_data->get_tuple_var_header ();
    -      data_offset = 0;
    -    }
    -
    -    bool get_shared_indices (hb_vector_t &shared_indices /* OUT */)
    -    {
    -      if (var_data->has_shared_point_numbers ())
    -      {
    -        const HBUINT8 *base = &(var_data+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;
    -        data_offset = p - base;
    -      }
    -      return true;
    -    }
    -
    -    bool is_valid () const
    -    {
    -      return (index < var_data->tupleVarCount.get_count ()) &&
    -             var_data_bytes.check_range (current_tuple, TupleVariationHeader::min_size) &&
    -             var_data_bytes.check_range (current_tuple, hb_max (current_tuple->get_data_size (),
    -                                                                current_tuple->get_size (axis_count)));
    -    }
    -
    -    bool move_to_next ()
    -    {
    -      data_offset += current_tuple->get_data_size ();
    -      current_tuple = ¤t_tuple->get_next (axis_count);
    -      index++;
    -      return is_valid ();
    -    }
    -
    -    const HBUINT8 *get_serialized_data () const
    -    { return &(var_data+var_data->data) + data_offset; }
    -
    -    private:
    -    const GlyphVariationData *var_data;
    -    unsigned int index;
    -    unsigned int axis_count;
    -    unsigned int data_offset;
    -
    -    public:
    -    hb_bytes_t var_data_bytes;
    -    const TupleVariationHeader *current_tuple;
    -  };
    -
    -  static bool get_tuple_iterator (hb_bytes_t var_data_bytes, unsigned axis_count,
    -                                  hb_vector_t &shared_indices /* OUT */,
    -                                  tuple_iterator_t *iterator /* OUT */)
    -  {
    -    iterator->init (var_data_bytes, axis_count);
    -    if (!iterator->get_shared_indices (shared_indices))
    -      return false;
    -    return iterator->is_valid ();
    -  }
    -
    -  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)
    -  {
    -    enum packed_point_flag_t
    -    {
    -      POINTS_ARE_WORDS     = 0x80,
    -      POINT_RUN_COUNT_MASK = 0x7F
    -    };
    -
    -    if (unlikely (p + 1 > end)) return false;
    -
    -    unsigned count = *p++;
    -    if (count & POINTS_ARE_WORDS)
    -    {
    -      if (unlikely (p + 1 > end)) return false;
    -      count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
    -    }
    -    if (unlikely (!points.resize (count, false))) return false;
    -
    -    unsigned n = 0;
    -    unsigned i = 0;
    -    while (i < count)
    -    {
    -      if (unlikely (p + 1 > end)) return false;
    -      unsigned control = *p++;
    -      unsigned run_count = (control & POINT_RUN_COUNT_MASK) + 1;
    -      if (unlikely (i + run_count > count)) return false;
    -      unsigned j;
    -      if (control & POINTS_ARE_WORDS)
    -      {
    -        if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
    -        for (j = 0; j < run_count; j++, i++)
    -        {
    -          n += *(const HBUINT16 *)p;
    -          points.arrayZ[i] = n;
    -          p += HBUINT16::static_size;
    -        }
    -      }
    -      else
    -      {
    -        if (unlikely (p + run_count > end)) return false;
    -        for (j = 0; j < run_count; j++, i++)
    -        {
    -          n += *p++;
    -          points.arrayZ[i] = n;
    -        }
    -      }
    -    }
    -    return true;
    -  }
    -
    -  static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
    -                             hb_vector_t &deltas /* IN/OUT */,
    -                             const HBUINT8 *end)
    -  {
    -    enum packed_delta_flag_t
    -    {
    -      DELTAS_ARE_ZERO      = 0x80,
    -      DELTAS_ARE_WORDS     = 0x40,
    -      DELTA_RUN_COUNT_MASK = 0x3F
    -    };
    -
    -    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;
    -      if (unlikely (i + run_count > count)) return false;
    -      unsigned j;
    -      if (control & DELTAS_ARE_ZERO)
    -      {
    -        for (j = 0; j < run_count; j++, i++)
    -          deltas.arrayZ[i] = 0;
    -      }
    -      else if (control & DELTAS_ARE_WORDS)
    -      {
    -        if (unlikely (p + run_count * HBUINT16::static_size > end)) return false;
    -        for (j = 0; j < run_count; j++, i++)
    -        {
    -          deltas.arrayZ[i] = * (const HBINT16 *) p;
    -          p += HBUINT16::static_size;
    -        }
    -      }
    -      else
    -      {
    -        if (unlikely (p + run_count > end)) return false;
    -        for (j = 0; j < run_count; j++, i++)
    -        {
    -          deltas.arrayZ[i] = * (const HBINT8 *) p++;
    -        }
    -      }
    -    }
    -    return true;
    -  }
    -
    -  bool has_data () const { return tupleVarCount; }
    -
    -  protected:
    -  struct TupleVarCount : HBUINT16
    -  {
    -    bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
    -    unsigned int get_count () const { return (*this) & CountMask; }
    -
    -    protected:
    -    enum Flags
    -    {
    -      SharedPointNumbers= 0x8000u,
    -      CountMask         = 0x0FFFu
    -    };
    -    public:
    -    DEFINE_SIZE_STATIC (2);
    -  };
    -
    -  TupleVarCount tupleVarCount;  /* A packed field. The high 4 bits are flags, and the
    -                                 * 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
    -                data;           /* Offset from the start of the GlyphVariationData table
    -                                 * to the serialized data. */
    -  /* TupleVariationHeader tupleVariationHeaders[] *//* Array of tuple variation headers. */
    -  public:
    -  DEFINE_SIZE_MIN (4);
    -};
    +struct GlyphVariationData : TupleVariationData
    +{};
     
     struct gvar
     {
    @@ -406,8 +104,8 @@
         return_trace (c->check_struct (this) && (version.major == 1) &&
                       sharedTuples.sanitize (c, this, axisCount * sharedTupleCount) &&
                       (is_long_offset () ?
    -                     c->check_array (get_long_offset_array (), glyphCount+1) :
    -                     c->check_array (get_short_offset_array (), glyphCount+1)));
    +                     c->check_array (get_long_offset_array (), c->get_num_glyphs () + 1) :
    +                     c->check_array (get_short_offset_array (), c->get_num_glyphs () + 1)));
       }
     
       /* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */
    @@ -418,6 +116,8 @@
       {
         TRACE_SUBSET (this);
     
    +    unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0;
    +
         gvar *out = c->serializer->allocate_min ();
         if (unlikely (!out)) return_trace (false);
     
    @@ -427,7 +127,7 @@
         out->sharedTupleCount = sharedTupleCount;
     
         unsigned int num_glyphs = c->plan->num_output_glyphs ();
    -    out->glyphCount = num_glyphs;
    +    out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
     
         unsigned int subset_data_size = 0;
         for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
    @@ -436,7 +136,7 @@
         {
           hb_codepoint_t old_gid;
           if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
    -      subset_data_size += get_glyph_var_data_bytes (c->source_blob, old_gid).length;
    +      subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length;
         }
     
         bool long_offset = subset_data_size & ~0xFFFFu;
    @@ -468,7 +168,9 @@
         {
           hb_codepoint_t old_gid;
           hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid)
    -                                ? get_glyph_var_data_bytes (c->source_blob, old_gid)
    +                                ? get_glyph_var_data_bytes (c->source_blob,
    +                                                            glyph_count,
    +                                                            old_gid)
                                     : hb_bytes_t ();
     
           if (long_offset)
    @@ -490,10 +192,12 @@
       }
     
       protected:
    -  const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob, hb_codepoint_t glyph) const
    +  const hb_bytes_t get_glyph_var_data_bytes (hb_blob_t *blob,
    +                                             unsigned glyph_count,
    +                                             hb_codepoint_t glyph) const
       {
    -    unsigned start_offset = get_offset (glyph);
    -    unsigned end_offset = get_offset (glyph+1);
    +    unsigned start_offset = get_offset (glyph_count, glyph);
    +    unsigned end_offset = get_offset (glyph_count, glyph+1);
         if (unlikely (end_offset < start_offset)) return hb_bytes_t ();
         unsigned length = end_offset - start_offset;
         hb_bytes_t var_data = blob->as_bytes ().sub_array (((unsigned) dataZ) + start_offset, length);
    @@ -502,9 +206,9 @@
     
       bool is_long_offset () const { return flags & 1; }
     
    -  unsigned get_offset (unsigned i) const
    +  unsigned get_offset (unsigned glyph_count, unsigned i) const
       {
    -    if (unlikely (i > glyphCount)) return 0;
    +    if (unlikely (i > glyph_count)) return 0;
         _hb_compiler_memory_r_barrier ();
         return is_long_offset () ? get_long_offset_array ()[i] : get_short_offset_array ()[i] * 2;
       }
    @@ -516,7 +220,38 @@
       struct accelerator_t
       {
         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;
    +
    +      /* For shared tuples that only have one axis active, shared the index of
    +       * that axis as a cache. This will speed up caclulate_scalar() a lot
    +       * for fonts with lots of axes and many "monovar" tuples. */
    +      hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
    +      unsigned count = table->sharedTupleCount;
    +      if (unlikely (!shared_tuple_active_idx.resize (count, false))) return;
    +      unsigned axis_count = table->axisCount;
    +      for (unsigned i = 0; i < count; i++)
    +      {
    +        hb_array_t tuple = shared_tuples.sub_array (axis_count * i, axis_count);
    +        int idx = -1;
    +        for (unsigned j = 0; j < axis_count; j++)
    +        {
    +          F2DOT14 peak = tuple.arrayZ[j];
    +          if (peak.to_int () != 0)
    +          {
    +            if (idx != -1)
    +            {
    +              idx = -1;
    +              break;
    +            }
    +            idx = j;
    +          }
    +        }
    +        shared_tuple_active_idx[i] = idx;
    +      }
    +    }
         ~accelerator_t () { table.destroy (); }
     
         private:
    @@ -554,30 +289,26 @@
         {
           if (!coords) return true;
     
    -      if (unlikely (glyph >= table->glyphCount)) return true;
    +      if (unlikely (glyph >= glyphCount)) return true;
     
    -      hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyph);
    +      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;
           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;
    -      orig_points_vec.extend (points);
    -      if (unlikely (orig_points_vec.in_error ())) return false;
    +      contour_point_vector_t orig_points_vec; // Populated lazily
           auto orig_points = orig_points_vec.as_array ();
     
    -      contour_point_vector_t deltas_vec; /* flag is used to indicate referenced point */
    -      if (unlikely (!deltas_vec.resize (points.length, false))) return false;
    +      /* flag is used to indicate referenced point */
    +      contour_point_vector_t deltas_vec; // Populated lazily
           auto deltas = deltas_vec.as_array ();
     
    -      hb_vector_t end_points;
    -      for (unsigned i = 0; i < points.length; ++i)
    -        if (points.arrayZ[i].is_end_point)
    -          end_points.push (i);
    +      hb_vector_t end_points; // Populated lazily
     
           unsigned num_coords = table->axisCount;
           hb_array_t shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
    @@ -585,15 +316,23 @@
           hb_vector_t private_indices;
           hb_vector_t x_deltas;
           hb_vector_t y_deltas;
    +      bool flush = false;
           do
           {
    -        float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples);
    +        float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples,
    +                                                                 shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx);
             if (scalar == 0.f) continue;
             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)))
               return false;
     
    +        if (!deltas)
    +        {
    +          if (unlikely (!deltas_vec.resize (points.length))) return false;
    +          deltas = deltas_vec.as_array ();
    +        }
    +
             const HBUINT8 *end = p + length;
     
             bool has_private_points = iterator.current_tuple->has_private_points ();
    @@ -609,16 +348,37 @@
             if (unlikely (!y_deltas.resize (num_deltas, false))) return false;
             if (unlikely (!GlyphVariationData::unpack_deltas (p, y_deltas, end))) return false;
     
    -        hb_memset (deltas.arrayZ, 0, deltas.get_size ());
    +        if (!apply_to_all)
    +        {
    +          if (!orig_points)
    +          {
    +            orig_points_vec.extend (points);
    +            if (unlikely (orig_points_vec.in_error ())) return false;
    +            orig_points = orig_points_vec.as_array ();
    +          }
    +
    +          if (flush)
    +          {
    +            for (unsigned int i = 0; i < points.length; i++)
    +              points.arrayZ[i].translate (deltas.arrayZ[i]);
    +            flush = false;
    +
    +          }
    +          hb_memset (deltas.arrayZ, 0, deltas.get_size ());
    +        }
     
    -        unsigned ref_points = 0;
             if (scalar != 1.0f)
               for (unsigned int i = 0; i < num_deltas; i++)
               {
    -            unsigned int pt_index = apply_to_all ? i : indices[i];
    -            if (unlikely (pt_index >= deltas.length)) continue;
    +            unsigned int pt_index;
    +            if (apply_to_all)
    +              pt_index = i;
    +            else
    +            {
    +              pt_index = indices[i];
    +              if (unlikely (pt_index >= deltas.length)) continue;
    +            }
                 auto &delta = deltas.arrayZ[pt_index];
    -            ref_points += !delta.flag;
                 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;
    @@ -626,23 +386,34 @@
             else
               for (unsigned int i = 0; i < num_deltas; i++)
               {
    -            unsigned int pt_index = apply_to_all ? i : indices[i];
    -            if (unlikely (pt_index >= deltas.length)) continue;
    +            unsigned int pt_index;
    +            if (apply_to_all)
    +              pt_index = i;
    +            else
    +            {
    +              pt_index = indices[i];
    +              if (unlikely (pt_index >= deltas.length)) continue;
    +            }
                 auto &delta = deltas.arrayZ[pt_index];
    -            ref_points += !delta.flag;
                 delta.flag = 1;     /* this point is referenced, i.e., explicit deltas specified */
                 delta.x += x_deltas.arrayZ[i];
                 delta.y += y_deltas.arrayZ[i];
               }
     
             /* infer deltas for unreferenced points */
    -        if (ref_points && ref_points < orig_points.length)
    +        if (!apply_to_all)
             {
    -          unsigned start_point = 0;
    -          for (unsigned c = 0; c < end_points.length; c++)
    +          if (!end_points)
               {
    -            unsigned end_point = end_points.arrayZ[c];
    +            for (unsigned i = 0; i < points.length; ++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)
    +          {
                 /* 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++)
    @@ -689,14 +460,14 @@
               }
             }
     
    -        /* apply specified / inferred deltas to points */
    -        for (unsigned int i = 0; i < points.length; i++)
    -        {
    -          points.arrayZ[i].x += deltas.arrayZ[i].x;
    -          points.arrayZ[i].y += deltas.arrayZ[i].y;
    -        }
    +        flush = true;
    +
           } while (iterator.move_to_next ());
     
    +      if (flush)
    +        for (unsigned int i = 0; i < points.length; i++)
    +          points.arrayZ[i].translate (deltas.arrayZ[i]);
    +
           return true;
         }
     
    @@ -704,6 +475,8 @@
     
         private:
         hb_blob_ptr_t table;
    +    unsigned glyphCount;
    +    hb_vector_t shared_tuple_active_idx;
       };
     
       protected:
    @@ -719,7 +492,7 @@
       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      glyphCount;     /* The number of glyphs in this font. This must match the number of
    +  HBUINT16      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
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -185,12 +185,8 @@
         {
           retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS;
           outer_map.add (0);
    -      for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
    -      {
    -        hb_codepoint_t old_gid;
    -        if (plan->old_gid_for_new_gid (gid, &old_gid))
    -          inner_sets[0]->add (old_gid);
    -      }
    +      for (hb_codepoint_t old_gid : plan->glyphset()->iter())
    +        inner_sets[0]->add (old_gid);
           hb_set_union (adv_set, inner_sets[0]);
         }
     
    @@ -202,10 +198,12 @@
         if (retain_adv_map)
         {
           for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
    +      {
             if (inner_sets[0]->has (gid))
               inner_maps[0].add (gid);
             else
               inner_maps[0].skip ();
    +      }
         }
         else
         {
    @@ -265,6 +263,9 @@
                       rsbMap.sanitize (c, this));
       }
     
    +  const VariationStore& get_var_store () const
    +  { return this+varStore; }
    +
       void listup_index_maps (hb_vector_t &index_maps) const
       {
         index_maps.push (&(this+advMap));
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-outline.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-outline.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-outline.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-outline.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -4,7 +4,6 @@
      * Copyright © 2005  Werner Lemberg
      * Copyright © 2013-2015  Alexei Podtelezhnikov
      *
    - *
      *  This is part of HarfBuzz, a text shaping library.
      *
      * Permission is hereby granted, without written agreement and without
    @@ -85,7 +84,7 @@
       }
     }
     
    -float hb_outline_t::area () const
    +float hb_outline_t::control_area () const
     {
       float a = 0;
       unsigned first = 0;
    @@ -118,7 +117,7 @@
       x_strength /= 2.f;
       y_strength /= 2.f;
     
    -  bool orientation_negative = area () < 0;
    +  bool orientation_negative = control_area () < 0;
     
       signed first = 0;
       for (unsigned c = 0; c < contours.length; c++)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-outline.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-outline.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-outline.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-outline.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -68,7 +68,7 @@
       void reset () { points.shrink (0, false); contours.resize (0); }
     
       HB_INTERNAL void replay (hb_draw_funcs_t *pen, void *pen_data) const;
    -  HB_INTERNAL float area () const;
    +  HB_INTERNAL float control_area () const;
       HB_INTERNAL void embolden (float x_strength, float y_strength,
                                  float x_shift, float y_shift);
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-paint.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-paint.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-paint.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-paint.h	2023-10-06 05:33:33.000000000 +0000
    @@ -616,7 +616,7 @@
       HB_PAINT_COMPOSITE_MODE_HSL_HUE,
       HB_PAINT_COMPOSITE_MODE_HSL_SATURATION,
       HB_PAINT_COMPOSITE_MODE_HSL_COLOR,
    -  HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY,
    +  HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY
     } hb_paint_composite_mode_t;
     
     /**
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-paint.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-paint.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-paint.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-paint.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -203,8 +203,8 @@
         if (!a)
           return false;
     
    -    float cc = cosf (a * (float) M_PI);
    -    float ss = sinf (a * (float) M_PI);
    +    float cc = cosf (a * HB_PI);
    +    float ss = sinf (a * HB_PI);
         push_transform (paint_data, cc, ss, -ss, cc, 0.f, 0.f);
         return true;
       }
    @@ -216,8 +216,8 @@
         if (!sx && !sy)
           return false;
     
    -    float x = tanf (-sx * (float) M_PI);
    -    float y = tanf (+sy * (float) M_PI);
    +    float x = tanf (-sx * HB_PI);
    +    float y = tanf (+sy * HB_PI);
         push_transform (paint_data, 1.f, y, x, 1.f, 0.f, 0.f);
         return true;
       }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-pool.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-pool.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-pool.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-pool.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -29,7 +29,16 @@
     
     #include "hb.hh"
     
    -/* Memory pool for persistent allocation of small objects. */
    +/* Memory pool for persistent allocation of small objects.
    + *
    + * Some AI musings on this, not necessarily true:
    + *
    + * This is a very simple implementation, but it's good enough for our
    + * purposes.  It's not thread-safe.  It's not very fast.  It's not
    + * very memory efficient.  It's not very cache efficient.  It's not
    + * very anything efficient.  But it's simple and it works.  And it's
    + * good enough for our purposes.  If you need something more
    + * sophisticated, use a real allocator.  Or use a real language. */
     
     template 
     struct hb_pool_t
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -35,6 +35,12 @@
      *
      * Priority queue implemented as a binary heap. Supports extract minimum
      * and insert operations.
    + *
    + * The priority queue is implemented as a binary heap, which is a complete
    + * binary tree. The root of the tree is the minimum element. The heap
    + * property is that the priority of a node is less than or equal to the
    + * priority of its children. The heap is stored in an array, with the
    + * children of node i stored at indices 2i + 1 and 2i + 2.
      */
     struct hb_priority_queue_t
     {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -228,6 +228,18 @@
     
       unsigned get_edit_count () { return edit_count; }
     
    +
    +  bool check_ops(unsigned count)
    +  {
    +    /* Avoid underflow */
    +    if (unlikely (this->max_ops < 0 || count >= (unsigned) this->max_ops))
    +    {
    +      this->max_ops = -1;
    +      return false;
    +    }
    +    return (this->max_ops -= (int) count) > 0;
    +  }
    +
       bool check_range (const void *base,
                         unsigned int len) const
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-shape.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-shape.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-shape.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-shape.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -196,4 +196,250 @@
     }
     
     
    +#ifdef HB_EXPERIMENTAL_API
    +
    +static float
    +buffer_advance (hb_buffer_t *buffer)
    +{
    +  float a = 0;
    +  auto *pos = buffer->pos;
    +  unsigned count = buffer->len;
    +  if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
    +    for (unsigned i = 0; i < count; i++)
    +      a += pos[i].x_advance;
    +  else
    +    for (unsigned i = 0; i < count; i++)
    +      a += pos[i].y_advance;
    +  return a;
    +}
    +
    +static void
    +reset_buffer (hb_buffer_t *buffer,
    +              hb_array_t text)
    +{
    +  assert (buffer->ensure (text.length));
    +  buffer->have_positions = false;
    +  buffer->len = text.length;
    +  memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0]));
    +  hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
    +}
    +
    +/**
    + * hb_shape_justify:
    + * @font: a mutable #hb_font_t to use for shaping
    + * @buffer: an #hb_buffer_t to shape
    + * @features: (array length=num_features) (nullable): an array of user
    + *    specified #hb_feature_t or `NULL`
    + * @num_features: the length of @features array
    + * @shaper_list: (array zero-terminated=1) (nullable): a `NULL`-terminated
    + *    array of shapers to use or `NULL`
    + * @min_target_advance: Minimum advance width/height to aim for.
    + * @max_target_advance: Maximum advance width/height to aim for.
    + * @advance: (inout): Input/output advance width/height of the buffer.
    + * @var_tag: (out): Variation-axis tag used for justification.
    + * @var_value: (out): Variation-axis value used to reach target justification.
    + *
    + * See hb_shape_full() for basic details. If @shaper_list is not `NULL`, the specified
    + * shapers will be used in the given order, otherwise the default shapers list
    + * will be used.
    + *
    + * In addition, justify the shaping results such that the shaping results reach
    + * the target advance width/height, depending on the buffer direction.
    + *
    + * If the advance of the buffer shaped with hb_shape_full() is already known,
    + * put that in *advance. Otherwise set *advance to zero.
    + *
    + * This API is currently experimental and will probably change in the future.
    + *
    + * Return value: false if all shapers failed, true otherwise
    + *
    + * XSince: EXPERIMENTAL
    + **/
    +hb_bool_t
    +hb_shape_justify (hb_font_t          *font,
    +                  hb_buffer_t        *buffer,
    +                  const hb_feature_t *features,
    +                  unsigned int        num_features,
    +                  const char * const *shaper_list,
    +                  float               min_target_advance,
    +                  float               max_target_advance,
    +                  float              *advance, /* IN/OUT */
    +                  hb_tag_t           *var_tag, /* OUT */
    +                  float              *var_value /* OUT */)
    +{
    +  // TODO Negative font scales?
    +
    +  /* If default advance already matches target, nothing to do. Shape and return. */
    +  if (min_target_advance <= *advance && *advance <= max_target_advance)
    +  {
    +    *var_tag = HB_TAG_NONE;
    +    *var_value = 0.0f;
    +    return hb_shape_full (font, buffer,
    +                          features, num_features,
    +                          shaper_list);
    +  }
    +
    +  hb_face_t *face = font->face;
    +
    +  /* Choose variation tag to use for justification. */
    +
    +  hb_tag_t tag = HB_TAG_NONE;
    +  hb_ot_var_axis_info_t axis_info;
    +
    +  hb_tag_t tags[] =
    +  {
    +    HB_TAG ('j','s','t','f'),
    +    HB_TAG ('w','d','t','h'),
    +  };
    +  for (unsigned i = 0; i < ARRAY_LENGTH (tags); i++)
    +    if (hb_ot_var_find_axis_info (face, tags[i], &axis_info))
    +    {
    +      tag = *var_tag = tags[i];
    +      break;
    +    }
    +
    +  /* If no suitable variation axis found, can't justify.  Just shape and return. */
    +  if (!tag)
    +  {
    +    *var_tag = HB_TAG_NONE;
    +    *var_value = 0.0f;
    +    if (hb_shape_full (font, buffer,
    +                       features, num_features,
    +                       shaper_list))
    +    {
    +      *advance = buffer_advance (buffer);
    +      return true;
    +    }
    +    else
    +      return false;
    +  }
    +
    +  /* Copy buffer text as we need it so we can shape multiple times. */
    +  unsigned text_len = buffer->len;
    +  auto *text_info = (hb_glyph_info_t *) hb_malloc (text_len * sizeof (buffer->info[0]));
    +  if (unlikely (text_len && !text_info))
    +    return false;
    +  hb_memcpy (text_info, buffer->info, text_len * sizeof (buffer->info[0]));
    +  auto text = hb_array (text_info, text_len);
    +
    +  /* If default advance was not provided to us, calculate it. */
    +  if (!*advance)
    +  {
    +    hb_font_set_variation (font, tag, axis_info.default_value);
    +    if (!hb_shape_full (font, buffer,
    +                        features, num_features,
    +                        shaper_list))
    +      return false;
    +    *advance = buffer_advance (buffer);
    +  }
    +
    +  /* If default advance already matches target, nothing to do. Shape and return.
    +   * Do this again, in case advance was just calculated.
    +   */
    +  if (min_target_advance <= *advance && *advance <= max_target_advance)
    +  {
    +    *var_tag = HB_TAG_NONE;
    +    *var_value = 0.0f;
    +    return true;
    +  }
    +
    +  /* Prepare for running the solver. */
    +  double a, b, ya, yb;
    +  if (*advance < min_target_advance)
    +  {
    +    /* Need to expand. */
    +    ya = (double) *advance;
    +    a = (double) axis_info.default_value;
    +    b = (double) axis_info.max_value;
    +
    +    /* Shape buffer for maximum expansion to use as other
    +     * starting point for the solver. */
    +    hb_font_set_variation (font, tag, (float) b);
    +    reset_buffer (buffer, text);
    +    if (!hb_shape_full (font, buffer,
    +                        features, num_features,
    +                        shaper_list))
    +      return false;
    +    yb = (double) buffer_advance (buffer);
    +    /* If the maximum expansion is less than max target,
    +     * there's nothing to solve for. Just return it. */
    +    if (yb <= (double) max_target_advance)
    +    {
    +      *var_value = (float) b;
    +      *advance = (float) yb;
    +      return true;
    +    }
    +  }
    +  else
    +  {
    +    /* Need to shrink. */
    +    yb = (double) *advance;
    +    a = (double) axis_info.min_value;
    +    b = (double) axis_info.default_value;
    +
    +    /* Shape buffer for maximum shrinkate to use as other
    +     * starting point for the solver. */
    +    hb_font_set_variation (font, tag, (float) a);
    +    reset_buffer (buffer, text);
    +    if (!hb_shape_full (font, buffer,
    +                        features, num_features,
    +                        shaper_list))
    +      return false;
    +    ya = (double) buffer_advance (buffer);
    +    /* If the maximum shrinkate is more than min target,
    +     * there's nothing to solve for. Just return it. */
    +    if (ya >= (double) min_target_advance)
    +    {
    +      *var_value = (float) a;
    +      *advance = (float) ya;
    +      return true;
    +    }
    +  }
    +
    +  /* Run the solver to find a var axis value that hits
    +   * the desired width. */
    +
    +  double epsilon = (b - a) / (1<<14);
    +  bool failed = false;
    +
    +  auto f = [&] (double x)
    +  {
    +    hb_font_set_variation (font, tag, (float) x);
    +    reset_buffer (buffer, text);
    +    if (unlikely (!hb_shape_full (font, buffer,
    +                                  features, num_features,
    +                                  shaper_list)))
    +    {
    +      failed = true;
    +      return (double) min_target_advance;
    +    }
    +
    +    double w = (double) buffer_advance (buffer);
    +    DEBUG_MSG (JUSTIFY, nullptr, "Trying '%c%c%c%c' axis parameter %f. Advance %g. Target: min %g max %g",
    +               HB_UNTAG (tag), x, w,
    +               (double) min_target_advance, (double) max_target_advance);
    +    return w;
    +  };
    +
    +  double y = 0;
    +  double itp = solve_itp (f,
    +                          a, b,
    +                          epsilon,
    +                          (double) min_target_advance, (double) max_target_advance,
    +                          ya, yb, y);
    +
    +  hb_free (text_info);
    +
    +  if (failed)
    +    return false;
    +
    +  *var_value = (float) itp;
    +  *advance = (float) y;
    +
    +  return true;
    +}
    +
    +#endif
    +
    +
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-shape.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-shape.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-shape.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-shape.h	2023-10-06 05:33:33.000000000 +0000
    @@ -53,6 +53,18 @@
                    unsigned int        num_features,
                    const char * const *shaper_list);
     
    +HB_EXTERN hb_bool_t
    +hb_shape_justify (hb_font_t          *font,
    +                  hb_buffer_t        *buffer,
    +                  const hb_feature_t *features,
    +                  unsigned int        num_features,
    +                  const char * const *shaper_list,
    +                  float               min_target_advance,
    +                  float               max_target_advance,
    +                  float              *advance, /* IN/OUT */
    +                  hb_tag_t           *var_tag, /* OUT */
    +                  float              *var_value /* OUT */);
    +
     HB_EXTERN const char **
     hb_shape_list_shapers (void);
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -39,7 +39,7 @@
     #endif
     
     #ifndef HB_NO_OT_SHAPE
    -HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
    +HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main shaper. */
     #endif
     
     #ifdef HAVE_UNISCRIBE
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-static.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-static.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-static.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-static.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -36,9 +36,11 @@
     #include "OT/Color/COLR/COLR.hh"
     #include "hb-ot-glyf-table.hh"
     #include "hb-ot-head-table.hh"
    +#include "hb-ot-hmtx-table.hh"
     #include "hb-ot-maxp-table.hh"
     
     #ifndef HB_NO_VISIBILITY
    +#include "hb-ot-name-language-static.hh"
     
     uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
     /*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
    @@ -108,4 +110,26 @@
     }
     
     
    +#ifndef HB_NO_VAR
    +bool
    +_glyf_get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical,
    +                                             int *lsb)
    +{
    +  return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb);
    +}
    +
    +unsigned
    +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
    +{
    +  return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical);
    +}
    +#endif
    +
    +bool
    +_glyf_get_leading_bearing_without_var_unscaled (hb_face_t *face, hb_codepoint_t gid, bool is_vertical, int *lsb)
    +{
    +  return face->table.glyf->get_leading_bearing_without_var_unscaled (gid, is_vertical, lsb);
    +}
    +
    +
     #endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-style.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-style.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-style.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-style.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -46,13 +46,13 @@
     static inline float
     _hb_angle_to_ratio (float a)
     {
    -  return tanf (a * float (-M_PI / 180.));
    +  return tanf (a * -HB_PI / 180.f);
     }
     
     static inline float
     _hb_ratio_to_angle (float r)
     {
    -  return atanf (r) * float (-180. / M_PI);
    +  return atanf (r) * -180.f / HB_PI;
     }
     
     /**
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -54,6 +54,7 @@
     #include "hb-ot-name-table.hh"
     #include "hb-ot-layout-gsub-table.hh"
     #include "hb-ot-layout-gpos-table.hh"
    +#include "hb-ot-var-cvar-table.hh"
     #include "hb-ot-var-fvar-table.hh"
     #include "hb-ot-var-gvar-table.hh"
     #include "hb-ot-var-hvar-table.hh"
    @@ -482,6 +483,16 @@
         if (plan->all_axes_pinned) return _subset (plan, buf);
         else return _passthrough (plan, tag);
     
    +  case HB_TAG ('c', 'v', 't', ' '):
    +#ifndef HB_NO_VAR
    +    if (_is_table_present (plan->source, HB_OT_TAG_cvar) &&
    +        plan->normalized_coords && !plan->pinned_at_default)
    +    {
    +      auto &cvar = *plan->source->table.cvar;
    +      return OT::cvar::add_cvt_and_apply_deltas (plan, cvar.get_tuple_var_data (), &cvar);
    +    }
    +#endif
    +    return _passthrough (plan, tag);
       default:
         if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED)
           return _passthrough (plan, tag);
    @@ -630,8 +641,3 @@
     end:
       return success ? hb_face_reference (plan->dest) : nullptr;
     }
    -
    -#ifndef HB_NO_VISIBILITY
    -/* If NO_VISIBILITY, libharfbuzz has this. */
    -#include "hb-ot-name-language-static.hh"
    -#endif
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset.h	2023-10-06 05:33:33.000000000 +0000
    @@ -71,6 +71,8 @@
      * in the final subset.
      * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
      * 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.
      *
      * List of boolean properties that can be configured on the subset input.
      *
    @@ -87,6 +89,7 @@
       HB_SUBSET_FLAGS_NOTDEF_OUTLINE =           0x00000040u,
       HB_SUBSET_FLAGS_GLYPH_NAMES =              0x00000080u,
       HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES =  0x00000100u,
    +  HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE =        0x00000200u,
     } hb_subset_flags_t;
     
     /**
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -71,7 +71,6 @@
       hb_tag_t default_no_subset_tables[] = {
         HB_TAG ('a', 'v', 'a', 'r'),
         HB_TAG ('g', 'a', 's', 'p'),
    -    HB_TAG ('c', 'v', 't', ' '),
         HB_TAG ('f', 'p', 'g', 'm'),
         HB_TAG ('p', 'r', 'e', 'p'),
         HB_TAG ('V', 'D', 'M', 'X'),
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc	2023-10-06 05:33:33.000000000 +0000
    @@ -36,8 +36,10 @@
     #include "hb-ot-layout-gpos-table.hh"
     #include "hb-ot-layout-gsub-table.hh"
     #include "hb-ot-cff1-table.hh"
    +#include "hb-ot-cff2-table.hh"
     #include "OT/Color/COLR/COLR.hh"
     #include "OT/Color/COLR/colrv1-closure.hh"
    +#include "OT/Color/CPAL/CPAL.hh"
     #include "hb-ot-var-fvar-table.hh"
     #include "hb-ot-var-avar-table.hh"
     #include "hb-ot-stat-table.hh"
    @@ -293,7 +295,7 @@
                                   feature_record_cond_idx_map,
                                   feature_substitutes_map);
     
    -  if (table_tag == HB_OT_TAG_GSUB)
    +  if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE))
         hb_ot_layout_lookups_substitute_closure (plan->source,
                                                  &lookup_indices,
                                                  gids_to_retain);
    @@ -345,7 +347,10 @@
       hb_font_t *font = hb_font_create (plan->source);
     
       hb_vector_t vars;
    -  vars.alloc (plan->user_axes_location.get_population ());
    +  if (!vars.alloc (plan->user_axes_location.get_population ())) {
    +    hb_font_destroy (font);
    +    return nullptr;
    +  }
     
       for (auto _ : plan->user_axes_location)
       {
    @@ -381,7 +386,13 @@
       bool collect_delta = plan->pinned_at_default ? false : true;
       if (collect_delta)
       {
    -    font = _get_hb_font_with_variations (plan);
    +    if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) {
    +      hb_font_destroy (font);
    +      gdef.destroy ();
    +      gpos.destroy ();
    +      return;
    +    }
    +
         if (gdef->has_var_store ())
         {
           var_store = &(gdef->get_var_store ());
    @@ -555,9 +566,12 @@
             if (plan->codepoint_to_glyph->has (cp))
               continue;
     
    -        hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
    -        plan->codepoint_to_glyph->set (cp, gid);
    -        plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
    +        hb_codepoint_t *gid;
    +        if (!unicode_glyphid_map->has(cp, &gid))
    +          continue;
    +
    +        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 ();
         }
    @@ -609,7 +623,7 @@
     
       gids_to_retain->add (gid);
     
    -  for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ())
    +  for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ())
         operation_count =
           _glyf_add_gid_and_children (glyf,
                                       item.get_gid (),
    @@ -617,10 +631,54 @@
                                       operation_count,
                                       depth);
     
    +#ifndef HB_NO_VAR_COMPOSITES
    +  for (auto &item : glyf.glyph_for_gid (gid).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;
     }
     
     static void
    +_nameid_closure (hb_subset_plan_t* plan,
    +                 hb_set_t* drop_tables)
    +{
    +#ifndef HB_NO_STYLE
    +  plan->source->table.STAT->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
    +#endif
    +#ifndef HB_NO_VAR
    +  if (!plan->all_axes_pinned)
    +    plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
    +#endif
    +#ifndef HB_NO_COLOR
    +  if (!drop_tables->has (HB_OT_TAG_CPAL))
    +    plan->source->table.CPAL->collect_name_ids (&plan->colr_palettes, &plan->name_ids);
    +#endif
    +
    +#ifndef HB_NO_SUBSET_LAYOUT
    +  if (!drop_tables->has (HB_OT_TAG_GPOS))
    +  {
    +    hb_blob_ptr_t gpos = plan->source_table ();
    +    gpos->collect_name_ids (&plan->gpos_features, &plan->name_ids);
    +    gpos.destroy ();
    +  }
    +  if (!drop_tables->has (HB_OT_TAG_GSUB))
    +  {
    +    hb_blob_ptr_t gsub = plan->source_table ();
    +    gsub->collect_name_ids (&plan->gsub_features, &plan->name_ids);
    +    gsub.destroy ();
    +  }
    +#endif
    +}
    +
    +static void
     _populate_gids_to_retain (hb_subset_plan_t* plan,
                               hb_set_t* drop_tables)
     {
    @@ -673,6 +731,7 @@
     
       plan->_glyphset_colred = cur_glyphset;
     
    +  _nameid_closure (plan, drop_tables);
       /* Populate a full set of glyphs to retain by adding all referenced
        * composite glyphs. */
       if (glyf.has_data ())
    @@ -756,21 +815,6 @@
       ;
     }
     
    -static void
    -_nameid_closure (hb_face_t *face,
    -                 hb_set_t  *nameids,
    -                 bool all_axes_pinned,
    -                 hb_hashmap_t *user_axes_location)
    -{
    -#ifndef HB_NO_STYLE
    -  face->table.STAT->collect_name_ids (user_axes_location, nameids);
    -#endif
    -#ifndef HB_NO_VAR
    -  if (!all_axes_pinned)
    -    face->table.fvar->collect_name_ids (user_axes_location, nameids);
    -#endif
    -}
    -
     #ifndef HB_NO_VAR
     static void
     _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
    @@ -783,12 +827,15 @@
     
       bool has_avar = face->table.avar->has_data ();
       const OT::SegmentMaps *seg_maps = nullptr;
    +  unsigned avar_axis_count = 0;
       if (has_avar)
    +  {
         seg_maps = face->table.avar->get_segment_maps ();
    +    avar_axis_count = face->table.avar->get_axis_count();
    +  }
     
       bool axis_not_pinned = false;
       unsigned old_axis_idx = 0, new_axis_idx = 0;
    -  unsigned int i = 0;
       for (const auto& axis : axes)
       {
         hb_tag_t axis_tag = axis.get_axis_tag ();
    @@ -803,7 +850,7 @@
         else
         {
           int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag));
    -      if (has_avar && old_axis_idx < face->table.avar->get_axis_count ())
    +      if (has_avar && old_axis_idx < avar_axis_count)
           {
             normalized_v = seg_maps->map (normalized_v);
           }
    @@ -811,17 +858,99 @@
           if (normalized_v != 0)
             plan->pinned_at_default = false;
     
    -      plan->normalized_coords[i] = normalized_v;
    +      plan->normalized_coords[old_axis_idx] = normalized_v;
         }
    -    if (has_avar)
    -      seg_maps = &StructAfter (*seg_maps);
     
         old_axis_idx++;
     
    -    i++;
    +    if (has_avar && old_axis_idx < avar_axis_count)
    +      seg_maps = &StructAfter (*seg_maps);
       }
       plan->all_axes_pinned = !axis_not_pinned;
     }
    +
    +static void
    +_update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan)
    +{
    +  if (!plan->normalized_coords) return;
    +  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_destroy (font);
    +    return;
    +  }
    +
    +  hb_glyph_extents_t extents = {0x7FFF, -0x7FFF};
    +  OT::hmtx_accelerator_t _hmtx (plan->source);
    +  float *hvar_store_cache = nullptr;
    +  if (_hmtx.has_data () && _hmtx.var_table.get_length ())
    +    hvar_store_cache = _hmtx.var_table->get_var_store ().create_cache ();
    +
    +  OT::vmtx_accelerator_t _vmtx (plan->source);
    +  float *vvar_store_cache = nullptr;
    +  if (_vmtx.has_data () && _vmtx.var_table.get_length ())
    +    vvar_store_cache = _vmtx.var_table->get_var_store ().create_cache ();
    +
    +  for (auto p : *plan->glyph_map)
    +  {
    +    hb_codepoint_t old_gid = p.first;
    +    hb_codepoint_t new_gid = p.second;
    +    if (!cff2.get_extents (font, old_gid, &extents)) continue;
    +    bool has_bounds_info = true;
    +    if (extents.x_bearing == 0 && extents.width == 0 &&
    +        extents.height == 0 && extents.y_bearing == 0)
    +      has_bounds_info = false;
    +
    +    if (has_bounds_info)
    +    {
    +      plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, extents.x_bearing);
    +      plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, extents.x_bearing + extents.width);
    +      plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, extents.y_bearing);
    +      plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, extents.y_bearing + extents.height);
    +    }
    +
    +    if (_hmtx.has_data ())
    +    {
    +      int hori_aw = _hmtx.get_advance_without_var_unscaled (old_gid);
    +      if (_hmtx.var_table.get_length ())
    +        hori_aw += (int) roundf (_hmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords,
    +                                                                              hvar_store_cache));
    +      int lsb = extents.x_bearing;
    +      if (!has_bounds_info)
    +      {
    +        if (!_hmtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
    +          continue;
    +      }
    +      plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
    +      plan->bounds_width_map.set (new_gid, extents.width);
    +    }
    +
    +    if (_vmtx.has_data ())
    +    {
    +      int vert_aw = _vmtx.get_advance_without_var_unscaled (old_gid);
    +      if (_vmtx.var_table.get_length ())
    +        vert_aw += (int) roundf (_vmtx.var_table->get_advance_delta_unscaled (old_gid, font->coords, font->num_coords,
    +                                                                              vvar_store_cache));
    +
    +      int tsb = extents.y_bearing;
    +      if (!has_bounds_info)
    +      {
    +        if (!_vmtx.get_leading_bearing_without_var_unscaled (old_gid, &tsb))
    +          continue;
    +      }
    +      plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
    +      plan->bounds_height_map.set (new_gid, extents.height);
    +    }
    +  }
    +  hb_font_destroy (font);
    +  if (hvar_store_cache)
    +    _hmtx.var_table->get_var_store ().destroy_cache (hvar_store_cache);
    +  if (vvar_store_cache)
    +    _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache);
    +}
     #endif
     
     hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
    @@ -884,6 +1013,8 @@
       _populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, this);
     
       _populate_gids_to_retain (this, input->sets.drop_tables);
    +  if (unlikely (in_error ()))
    +    return;
     
       _create_old_gid_to_new_gid_map (face,
                                       input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
    @@ -905,10 +1036,13 @@
             glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second);
       }
     
    -  _nameid_closure (face, &name_ids, all_axes_pinned, &user_axes_location);
       if (unlikely (in_error ()))
         return;
     
    +#ifndef HB_NO_VAR
    +  _update_instance_metrics_map_from_cff2 (this);
    +#endif
    +
       if (attach_accelerator_data)
       {
         hb_multimap_t gid_to_unicodes;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -211,7 +211,7 @@
       template
       hb_blob_ptr_t source_table()
       {
    -    hb_lock_t (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
    +    hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
     
         auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache;
         if (cache
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-unicode.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-unicode.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-unicode.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-unicode.h	2023-10-06 05:33:33.000000000 +0000
    @@ -164,7 +164,7 @@
      * @HB_UNICODE_COMBINING_CLASS_CCC122: [Lao]
      * @HB_UNICODE_COMBINING_CLASS_CCC129: [Tibetan]
      * @HB_UNICODE_COMBINING_CLASS_CCC130: [Tibetan]
    - * @HB_UNICODE_COMBINING_CLASS_CCC133: [Tibetan]
    + * @HB_UNICODE_COMBINING_CLASS_CCC132: [Tibetan] Since: 7.2.0
      * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: Marks attached at the bottom left
      * @HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: Marks attached directly below
      * @HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: Marks attached directly above
    @@ -246,7 +246,7 @@
       /* Tibetan */
       HB_UNICODE_COMBINING_CLASS_CCC129     = 129,
       HB_UNICODE_COMBINING_CLASS_CCC130     = 130,
    -  HB_UNICODE_COMBINING_CLASS_CCC133     = 132,
    +  HB_UNICODE_COMBINING_CLASS_CCC132     = 132,
     
     
       HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT        = 200,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-version.h openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-version.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/hb-version.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/hb-version.h	2023-10-06 05:33:33.000000000 +0000
    @@ -47,20 +47,20 @@
      *
      * The minor component of the library version available at compile-time.
      */
    -#define HB_VERSION_MINOR 0
    +#define HB_VERSION_MINOR 2
     /**
      * HB_VERSION_MICRO:
      *
      * The micro component of the library version available at compile-time.
      */
    -#define HB_VERSION_MICRO 1
    +#define HB_VERSION_MICRO 0
     
     /**
      * HB_VERSION_STRING:
      *
      * A string literal containing the library version available at compile-time.
      */
    -#define HB_VERSION_STRING "7.0.1"
    +#define HB_VERSION_STRING "7.2.0"
     
     /**
      * HB_VERSION_ATLEAST:
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -40,7 +40,6 @@
      */
     #define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
     
    -
     namespace OT {
     struct hb_paint_context_t;
     }
    @@ -242,10 +241,15 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { value.closurev1 (c); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
    -    if (!value.subset (c)) return_trace (false);
    +    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));
       }
     
    @@ -296,10 +300,11 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { value.closurev1 (c); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
    -    return_trace (value.subset (c));
    +    return_trace (value.subset (c, instancer, varIdxBase));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -337,11 +342,20 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { c->add_palette_index (paletteIndex); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (*this);
         if (unlikely (!out)) return_trace (false);
    +
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->stopOffset.set_float (stopOffset.to_float(instancer (varIdxBase, 0)));
    +      out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 1)));
    +    }
    +
         return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
                                                    HB_SERIALIZE_ERROR_INT_OVERFLOW));
       }
    @@ -390,7 +404,8 @@
           stop.closurev1 (c);
       }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->start_embed (this);
    @@ -402,7 +417,7 @@
     
         for (const auto& stop : stops.iter ())
         {
    -      if (!stop.subset (c)) return_trace (false);
    +      if (!stop.subset (c, instancer)) return_trace (false);
         }
         return_trace (true);
       }
    @@ -523,6 +538,25 @@
         return_trace (c->check_struct (this));
       }
     
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
    +  {
    +    TRACE_SUBSET (this);
    +    auto *out = c->serializer->embed (*this);
    +    if (unlikely (!out)) return_trace (false);
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->xx.set_float (xx.to_float(instancer (varIdxBase, 0)));
    +      out->yx.set_float (yx.to_float(instancer (varIdxBase, 1)));
    +      out->xy.set_float (xy.to_float(instancer (varIdxBase, 2)));
    +      out->yy.set_float (yy.to_float(instancer (varIdxBase, 3)));
    +      out->dx.set_float (dx.to_float(instancer (varIdxBase, 4)));
    +      out->dy.set_float (dy.to_float(instancer (varIdxBase, 5)));
    +    }
    +    return_trace (true);
    +  }
    +
       void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
       {
         c->funcs->push_transform (c->data,
    @@ -548,7 +582,8 @@
     {
       void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer HB_UNUSED) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
    @@ -579,11 +614,20 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { c->add_palette_index (paletteIndex); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (*this);
         if (unlikely (!out)) return_trace (false);
    +
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +      out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 0)));
    +
    +    if (format == 3 && c->plan->all_axes_pinned)
    +        out->format = 2;
    +
         return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
                                                    HB_SERIALIZE_ERROR_INT_OVERFLOW));
       }
    @@ -618,13 +662,28 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { (this+colorLine).closurev1 (c); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
    +      out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
    +      out->x1 = x1 + (int) roundf (instancer (varIdxBase, 2));
    +      out->y1 = y1 + (int) roundf (instancer (varIdxBase, 3));
    +      out->x2 = x2 + (int) roundf (instancer (varIdxBase, 4));
    +      out->y2 = y2 + (int) roundf (instancer (varIdxBase, 5));
    +    }
    +
    +    if (format == 5 && c->plan->all_axes_pinned)
    +        out->format = 4;
    +
    +    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -669,13 +728,28 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { (this+colorLine).closurev1 (c); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
    +      out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
    +      out->radius0 = radius0 + (unsigned) roundf (instancer (varIdxBase, 2));
    +      out->x1 = x1 + (int) roundf (instancer (varIdxBase, 3));
    +      out->y1 = y1 + (int) roundf (instancer (varIdxBase, 4));
    +      out->radius1 = radius1 + (unsigned) roundf (instancer (varIdxBase, 5));
    +    }
    +
    +    if (format == 7 && c->plan->all_axes_pinned)
    +        out->format = 6;
    +
    +    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -720,13 +794,26 @@
       void closurev1 (hb_colrv1_closure_context_t* c) const
       { (this+colorLine).closurev1 (c); }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->colorLine.serialize_subset (c, colorLine, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 0));
    +      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 1));
    +      out->startAngle.set_float (startAngle.to_float (instancer (varIdxBase, 2)));
    +      out->endAngle.set_float (endAngle.to_float (instancer (varIdxBase, 3)));
    +    }
    +
    +    if (format == 9 && c->plan->all_axes_pinned)
    +        out->format = 8;
    +
    +    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -746,8 +833,8 @@
         c->funcs->sweep_gradient (c->data, &cl,
                                   centerX + c->instancer (varIdxBase, 0),
                                   centerY + c->instancer (varIdxBase, 1),
    -                              (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * (float) M_PI,
    -                              (endAngle.to_float   (c->instancer (varIdxBase, 3)) + 1) * (float) M_PI);
    +                              (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * HB_PI,
    +                              (endAngle.to_float   (c->instancer (varIdxBase, 3)) + 1) * HB_PI);
       }
     
       HBUINT8                       format; /* format = 8(noVar) or 9 (Var) */
    @@ -766,7 +853,8 @@
     {
       void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
    @@ -776,7 +864,7 @@
                                            HB_SERIALIZE_ERROR_INT_OVERFLOW))
           return_trace (false);
     
    -    return_trace (out->paint.serialize_subset (c, paint, this));
    +    return_trace (out->paint.serialize_subset (c, paint, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -807,7 +895,8 @@
     {
       void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer HB_UNUSED) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
    @@ -836,13 +925,16 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
    -    if (!out->transform.serialize_copy (c->serializer, transform, this)) return_trace (false);
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (!out->transform.serialize_subset (c, transform, this, instancer)) return_trace (false);
    +    if (format == 13 && c->plan->all_axes_pinned)
    +      out->format = 12;
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -871,13 +963,24 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
    +      out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
    +    }
    +
    +    if (format == 15 && c->plan->all_axes_pinned)
    +        out->format = 14;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -908,13 +1011,24 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
    +      out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
    +    }
    +
    +    if (format == 17 && c->plan->all_axes_pinned)
    +        out->format = 16;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -945,13 +1059,26 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
    +      out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
    +      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
    +      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
    +    }
    +
    +    if (format == 19 && c->plan->all_axes_pinned)
    +        out->format = 18;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -990,13 +1117,21 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +      out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
    +
    +    if (format == 21 && c->plan->all_axes_pinned)
    +        out->format = 20;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1025,13 +1160,25 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
    +      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
    +      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
    +    }
    +
    +    if (format == 23 && c->plan->all_axes_pinned)
    +        out->format = 22;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1068,13 +1215,21 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +      out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
    +
    +    if (format == 25 && c->plan->all_axes_pinned)
    +      out->format = 24;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1103,13 +1258,25 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
    +      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
    +      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
    +    }
    +
    +    if (format ==27 && c->plan->all_axes_pinned)
    +        out->format = 26;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1146,13 +1313,24 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
    +      out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
    +    }
    +
    +    if (format == 29 && c->plan->all_axes_pinned)
    +        out->format = 28;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1183,13 +1361,26 @@
     {
       HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    return_trace (out->src.serialize_subset (c, src, this));
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
    +      out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
    +      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
    +      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
    +    }
    +
    +    if (format == 31 && c->plan->all_axes_pinned)
    +        out->format = 30;
    +
    +    return_trace (out->src.serialize_subset (c, src, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1228,14 +1419,15 @@
     {
       void closurev1 (hb_colrv1_closure_context_t* c) const;
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->embed (this);
         if (unlikely (!out)) return_trace (false);
     
    -    if (!out->src.serialize_subset (c, src, this)) return_trace (false);
    -    return_trace (out->backdrop.serialize_subset (c, backdrop, this));
    +    if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false);
    +    return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c) const
    @@ -1283,6 +1475,28 @@
         clip_box.yMax = yMax;
       }
     
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer,
    +               uint32_t varIdxBase) const
    +  {
    +    TRACE_SUBSET (this);
    +    auto *out = c->serializer->embed (*this);
    +    if (unlikely (!out)) return_trace (false);
    +
    +    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
    +    {
    +      out->xMin = xMin + (int) roundf (instancer (varIdxBase, 0));
    +      out->yMin = yMin + (int) roundf (instancer (varIdxBase, 1));
    +      out->xMax = xMax + (int) roundf (instancer (varIdxBase, 2));
    +      out->yMax = yMax + (int) roundf (instancer (varIdxBase, 3));
    +    }
    +
    +    if (format == 2 && c->plan->all_axes_pinned)
    +        out->format = 1;
    +
    +    return_trace (true);
    +  }
    +
       public:
       HBUINT8       format; /* format = 1(noVar) or 2(Var)*/
       FWORD         xMin;
    @@ -1310,13 +1524,14 @@
     
     struct ClipBox
     {
    -  ClipBox* copy (hb_serialize_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
    -    TRACE_SERIALIZE (this);
    +    TRACE_SUBSET (this);
         switch (u.format) {
    -    case 1: return_trace (reinterpret_cast (c->embed (u.format1)));
    -    case 2: return_trace (reinterpret_cast (c->embed (u.format2)));
    -    default:return_trace (nullptr);
    +    case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION));
    +    case 2: return_trace (u.format2.subset (c, instancer));
    +    default:return_trace (c->default_return_value ());
         }
       }
     
    @@ -1367,13 +1582,15 @@
       int cmp (hb_codepoint_t g) const
       { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
     
    -  ClipRecord* copy (hb_serialize_context_t *c, const void *base) const
    +  bool subset (hb_subset_context_t *c,
    +               const void *base,
    +               const VarStoreInstancer &instancer) const
       {
    -    TRACE_SERIALIZE (this);
    -    auto *out = c->embed (this);
    -    if (unlikely (!out)) return_trace (nullptr);
    -    if (!out->clipBox.serialize_copy (c, clipBox, base)) return_trace (nullptr);
    -    return_trace (out);
    +    TRACE_SUBSET (this);
    +    auto *out = c->serializer->embed (*this);
    +    if (unlikely (!out)) return_trace (false);
    +
    +    return_trace (out->clipBox.serialize_subset (c, clipBox, base, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c, const void *base) const
    @@ -1400,7 +1617,8 @@
     
     struct ClipList
     {
    -  unsigned serialize_clip_records (hb_serialize_context_t *c,
    +  unsigned serialize_clip_records (hb_subset_context_t *c,
    +                                   const VarStoreInstancer &instancer,
                                        const hb_set_t& gids,
                                        const hb_map_t& gid_offset_map) const
       {
    @@ -1432,7 +1650,7 @@
           record.endGlyphID = prev_gid;
           record.clipBox = prev_offset;
     
    -      if (!c->copy (record, this)) return_trace (0);
    +      if (!record.subset (c, this, instancer)) return_trace (0);
           count++;
     
           start_gid = _;
    @@ -1446,13 +1664,14 @@
           record.startGlyphID = start_gid;
           record.endGlyphID = prev_gid;
           record.clipBox = prev_offset;
    -      if (!c->copy (record, this)) return_trace (0);
    +      if (!record.subset (c, this, instancer)) return_trace (0);
           count++;
         }
         return_trace (count);
       }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->start_embed (*this);
    @@ -1477,7 +1696,7 @@
           }
         }
     
    -    unsigned count = serialize_clip_records (c->serializer, new_gids, new_gid_offset_map);
    +    unsigned count = serialize_clip_records (c, instancer, new_gids, new_gid_offset_map);
         if (!count) return_trace (false);
         return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
       }
    @@ -1611,7 +1830,8 @@
       { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
     
       bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
    -                  const void* src_base, hb_subset_context_t *c) const
    +                  const void* src_base, hb_subset_context_t *c,
    +                  const VarStoreInstancer &instancer) const
       {
         TRACE_SERIALIZE (this);
         auto *out = s->embed (this);
    @@ -1620,7 +1840,7 @@
                               HB_SERIALIZE_ERROR_INT_OVERFLOW))
           return_trace (false);
     
    -    return_trace (out->paint.serialize_subset (c, paint, src_base));
    +    return_trace (out->paint.serialize_subset (c, paint, src_base, instancer));
       }
     
       bool sanitize (hb_sanitize_context_t *c, const void *base) const
    @@ -1639,7 +1859,8 @@
     
     struct BaseGlyphList : SortedArray32Of
     {
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->start_embed (this);
    @@ -1651,7 +1872,7 @@
           unsigned gid = _.glyphId;
           if (!glyphset->has (gid)) continue;
     
    -      if (_.serialize (c->serializer, c->plan->glyph_map, this, c)) out->len++;
    +      if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++;
           else return_trace (false);
         }
     
    @@ -1670,7 +1891,8 @@
       const Paint& get_paint (unsigned i) const
       { return this+(*this)[i]; }
     
    -  bool subset (hb_subset_context_t *c) const
    +  bool subset (hb_subset_context_t *c,
    +               const VarStoreInstancer &instancer) const
       {
         TRACE_SUBSET (this);
         auto *out = c->serializer->start_embed (this);
    @@ -1681,7 +1903,7 @@
     
         {
           auto *o = out->serialize_append (c->serializer);
    -      if (unlikely (!o) || !o->serialize_subset (c, _.second, this))
    +      if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
             return_trace (false);
         }
         return_trace (true);
    @@ -1883,7 +2105,6 @@
       bool subset (hb_subset_context_t *c) const
       {
         TRACE_SUBSET (this);
    -
         const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
         const hb_set_t& glyphset = c->plan->_glyphset_colred;
     
    @@ -1954,7 +2175,12 @@
     
         auto snap = c->serializer->snapshot ();
         if (!c->serializer->allocate_size (5 * HBUINT32::static_size)) return_trace (false);
    -    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this))
    +
    +    VarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
    +                                 varIdxMap ? &(this+varIdxMap) : nullptr,
    +                                 c->plan->normalized_coords.as_array ());
    +
    +    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
    @@ -1964,8 +2190,11 @@
     
         if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
     
    -    colr_prime->layerList.serialize_subset (c, layerList, this);
    -    colr_prime->clipList.serialize_subset (c, clipList, this);
    +    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);
    @@ -1984,14 +2213,15 @@
           return nullptr;
       }
     
    +#ifndef HB_NO_PAINT
       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,
    +    VarStoreInstancer instancer (&(this+varStore),
    +                                 &(this+varIdxMap),
                                      hb_array (font->coords, font->num_coords));
     
         if (get_clip (glyph, extents, instancer))
    @@ -2022,6 +2252,7 @@
     
         return ret;
       }
    +#endif
     
       bool
       has_paint_for_glyph (hb_codepoint_t glyph) const
    @@ -2045,11 +2276,12 @@
                                             instancer);
       }
     
    +#ifndef HB_NO_PAINT
       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,
    +    VarStoreInstancer instancer (&(this+varStore),
    +                                 &(this+varIdxMap),
                                      hb_array (font->coords, font->num_coords));
         hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
     
    @@ -2060,8 +2292,8 @@
           {
             // COLRv1 glyph
     
    -        VarStoreInstancer instancer (this+varStore,
    -                                     this+varIdxMap,
    +        VarStoreInstancer instancer (&(this+varStore),
    +                                     &(this+varIdxMap),
                                          hb_array (font->coords, font->num_coords));
     
             bool is_bounded = true;
    @@ -2131,6 +2363,7 @@
     
         return false;
       }
    +#endif
     
       protected:
       HBUINT16      version;        /* Table version number (starts at 0). */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Color/CPAL/CPAL.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -73,6 +73,30 @@
       }
     
       public:
    +  void collect_name_ids (const void *base,
    +                         unsigned palette_count,
    +                         unsigned color_count,
    +                         const hb_map_t *color_index_map,
    +                         hb_set_t *nameids_to_retain /* OUT */) const
    +  {
    +    if (paletteLabelsZ)
    +    {
    +      + (base+paletteLabelsZ).as_array (palette_count)
    +      | hb_sink (nameids_to_retain)
    +      ;
    +    }
    +
    +    if (colorLabelsZ)
    +    {
    +      const hb_array_t colorLabels = (base+colorLabelsZ).as_array (color_count);
    +      for (unsigned i = 0; i < color_count; i++)
    +      {
    +        if (!color_index_map->has (i)) continue;
    +        nameids_to_retain->add (colorLabels[i]);
    +      }
    +    }
    +  }
    +
       bool serialize (hb_serialize_context_t *c,
                       unsigned palette_count,
                       unsigned color_count,
    @@ -95,13 +119,10 @@
         if (colorLabelsZ)
         {
           c->push ();
    -      for (const auto _ : colorLabels)
    +      for (unsigned i = 0; i < color_count; i++)
           {
    -        const hb_codepoint_t *v;
    -        if (!color_index_map->has (_, &v)) continue;
    -        NameID new_color_idx;
    -        new_color_idx = *v;
    -        if (!c->copy (new_color_idx))
    +        if (!color_index_map->has (i)) continue;
    +        if (!c->copy (colorLabels[i]))
             {
               c->pop_discard ();
               return_trace (false);
    @@ -189,6 +210,13 @@
         return numColors;
       }
     
    +  void collect_name_ids (const hb_map_t *color_index_map,
    +                         hb_set_t *nameids_to_retain /* OUT */) const
    +  {
    +    if (version == 1)
    +      v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain);
    +  }
    +
       private:
       const CPALV1Tail& v1 () const
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -87,27 +87,34 @@
         }
       }
     
    -  void transform_points (contour_point_vector_t &points) const
    +  void transform_points (contour_point_vector_t &points,
    +                         const float (&matrix)[4],
    +                         const contour_point_t &trans) const
       {
    -    float matrix[4];
    -    contour_point_t trans;
    -    if (get_transformation (matrix, trans))
    +    if (scaled_offsets ())
         {
    -      if (scaled_offsets ())
    -      {
    -        points.translate (trans);
    -        points.transform (matrix);
    -      }
    -      else
    -      {
    -        points.transform (matrix);
    -        points.translate (trans);
    -      }
    +      points.translate (trans);
    +      points.transform (matrix);
         }
    +    else
    +    {
    +      points.transform (matrix);
    +      points.translate (trans);
    +    }
    +  }
    +
    +  bool get_points (contour_point_vector_t &points) const
    +  {
    +    float matrix[4];
    +    contour_point_t trans;
    +    get_transformation (matrix, trans);
    +    if (unlikely (!points.resize (points.length + 1))) return false;
    +    points[points.length - 1] = trans;
    +    return true;
       }
     
    -  unsigned compile_with_deltas (const contour_point_t &p_delta,
    -                                char *out) const
    +  unsigned compile_with_point (const contour_point_t &point,
    +                               char *out) const
       {
         const HBINT8 *p = &StructAfter (flags);
     #ifndef HB_NO_BEYOND_64K
    @@ -121,18 +128,17 @@
         unsigned len_before_val = (const char *)p - (const char *)this;
         if (flags & ARG_1_AND_2_ARE_WORDS)
         {
    -      // no overflow, copy and update value with deltas
    +      // no overflow, copy value
           hb_memcpy (out, this, len);
     
    -      const HBINT16 *px = reinterpret_cast (p);
           HBINT16 *o = reinterpret_cast (out + len_before_val);
    -      o[0] = px[0] + roundf (p_delta.x);
    -      o[1] = px[1] + roundf (p_delta.y);
    +      o[0] = roundf (point.x);
    +      o[1] = roundf (point.y);
         }
         else
         {
    -      int new_x = p[0] + roundf (p_delta.x);
    -      int new_y = p[1] + roundf (p_delta.y);
    +      int new_x = roundf (point.x);
    +      int new_y = roundf (point.y);
           if (new_x <= 127 && new_x >= -128 &&
               new_y <= 127 && new_y >= -128)
           {
    @@ -143,7 +149,7 @@
           }
           else
           {
    -        // int8 overflows after deltas applied
    +        // new point value has an int8 overflow
             hb_memcpy (out, this, len_before_val);
     
             //update flags
    @@ -171,6 +177,7 @@
       bool scaled_offsets () const
       { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
     
    +  public:
       bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
       {
         matrix[0] = matrix[3] = 1.f;
    @@ -225,7 +232,6 @@
         return tx || ty;
       }
     
    -  public:
       hb_codepoint_t get_gid () const
       {
     #ifndef HB_NO_BEYOND_64K
    @@ -246,6 +252,27 @@
           StructAfter (flags) = gid;
       }
     
    +#ifndef HB_NO_BEYOND_64K
    +  void lower_gid_24_to_16 ()
    +  {
    +    hb_codepoint_t gid = get_gid ();
    +    if (!(flags & GID_IS_24BIT) || gid > 0xFFFFu)
    +      return;
    +
    +    /* Lower the flag and move the rest of the struct down. */
    +
    +    unsigned size = get_size ();
    +    char *end = (char *) this + size;
    +    char *p = &StructAfter (flags);
    +    p += HBGlyphID24::static_size;
    +
    +    flags = flags & ~GID_IS_24BIT;
    +    set_gid (gid);
    +
    +    memmove (p - HBGlyphID24::static_size + HBGlyphID16::static_size, p, end - p);
    +  }
    +#endif
    +
       protected:
       HBUINT16      flags;
       HBUINT24      pad;
    @@ -304,7 +331,7 @@
       }
     
       bool compile_bytes_with_deltas (const hb_bytes_t &source_bytes,
    -                                  const contour_point_vector_t &deltas,
    +                                  const contour_point_vector_t &points_with_deltas,
                                       hb_bytes_t &dest_bytes /* OUT */)
       {
         if (source_bytes.length <= GlyphHeader::static_size ||
    @@ -319,7 +346,7 @@
         /* try to allocate more memories than source glyph bytes
          * in case that there might be an overflow for int8 value
          * and we would need to use int16 instead */
    -    char *o = (char *) hb_calloc (source_len + source_len/2, sizeof (char));
    +    char *o = (char *) hb_calloc (source_len * 2, sizeof (char));
         if (unlikely (!o)) return false;
     
         const CompositeGlyphRecord *c = reinterpret_cast (source_bytes.arrayZ + GlyphHeader::static_size);
    @@ -329,8 +356,11 @@
         unsigned i = 0, source_comp_len = 0;
         for (const auto &component : it)
         {
    -      /* last 4 points in deltas are phantom points and should not be included */
    -      if (i >= deltas.length - 4) return false;
    +      /* last 4 points in points_with_deltas are phantom points and should not be included */
    +      if (i >= points_with_deltas.length - 4) {
    +        free (o);
    +        return false;
    +      }
     
           unsigned comp_len = component.get_size ();
           if (component.is_anchored ())
    @@ -340,7 +370,7 @@
           }
           else
           {
    -        unsigned new_len = component.compile_with_deltas (deltas[i], p);
    +        unsigned new_len = component.compile_with_point (points_with_deltas[i], p);
             p += new_len;
           }
           i++;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -31,6 +31,12 @@
     
       static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;
     
    +  static bool has_valid_glyf_format(const hb_face_t* face)
    +  {
    +    const OT::head &head = *face->table.head;
    +    return head.indexToLocFormat <= 1 && head.glyphDataFormat <= 1;
    +  }
    +
       bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
       {
         TRACE_SANITIZE (this);
    @@ -72,6 +78,13 @@
       {
         TRACE_SUBSET (this);
     
    +    if (!has_valid_glyf_format (c->plan->source)) {
    +      // glyf format is unknown don't attempt to subset it.
    +      DEBUG_MSG (SUBSET, nullptr,
    +                 "unkown glyf format, dropping from subset.");
    +      return_trace (false);
    +    }
    +
         glyf *glyf_prime = c->serializer->start_embed  ();
         if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
     
    @@ -85,11 +98,17 @@
         hb_vector_t padded_offsets;
         unsigned num_glyphs = c->plan->num_output_glyphs ();
         if (unlikely (!padded_offsets.resize (num_glyphs)))
    +    {
    +      hb_font_destroy (font);
           return false;
    +    }
     
         hb_vector_t glyphs;
         if (!_populate_subset_glyphs (c->plan, font, glyphs))
    +    {
    +      hb_font_destroy (font);
           return false;
    +    }
     
         if (font)
           hb_font_destroy (font);
    @@ -112,7 +131,7 @@
     
         bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan);
         if (c->plan->normalized_coords && !c->plan->pinned_at_default)
    -      _free_compiled_subset_glyphs (glyphs, glyphs.length - 1);
    +      _free_compiled_subset_glyphs (glyphs);
     
         if (!result) return false;
     
    @@ -131,9 +150,9 @@
       hb_font_t *
       _create_font_for_instancing (const hb_subset_plan_t *plan) const;
     
    -  void _free_compiled_subset_glyphs (hb_vector_t &glyphs, unsigned index) const
    +  void _free_compiled_subset_glyphs (hb_vector_t &glyphs) const
       {
    -    for (unsigned i = 0; i <= index && i < glyphs.length; i++)
    +    for (unsigned i = 0; i < glyphs.length; i++)
           glyphs[i].free_compiled_bytes ();
       }
     
    @@ -162,7 +181,7 @@
         vmtx = nullptr;
     #endif
         const OT::head &head = *face->table.head;
    -    if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
    +    if (!glyf::has_valid_glyf_format (face))
           /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
           return;
         short_offset = 0 == head.indexToLocFormat;
    @@ -222,6 +241,8 @@
         return true;
       }
     
    +  public:
    +
     #ifndef HB_NO_VAR
       struct points_aggregator_t
       {
    @@ -285,7 +306,6 @@
         contour_point_t *get_phantoms_sink () { return phantoms; }
       };
     
    -  public:
       unsigned
       get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
       {
    @@ -327,6 +347,15 @@
       }
     #endif
     
    +  bool get_leading_bearing_without_var_unscaled (hb_codepoint_t gid, bool is_vertical, int *lsb) const
    +  {
    +    if (unlikely (gid >= num_glyphs)) return false;
    +    if (is_vertical) return false; // TODO Humm, what to do here?
    +
    +    *lsb = glyph_for_gid (gid).get_header ()->xMin;
    +    return true;
    +  }
    +
       public:
       bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
       {
    @@ -405,7 +434,6 @@
       unsigned num_glyphs = plan->num_output_glyphs ();
       if (!glyphs.resize (num_glyphs)) return false;
     
    -  unsigned idx = 0;
       for (auto p : plan->glyph_map->iter ())
       {
         unsigned new_gid = p.second;
    @@ -433,11 +461,10 @@
           if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf)))
           {
             // when pinned at default, only bounds are updated, thus no need to free
    -        if (!plan->pinned_at_default && idx > 0)
    -          _free_compiled_subset_glyphs (glyphs, idx - 1);
    +        if (!plan->pinned_at_default)
    +          _free_compiled_subset_glyphs (glyphs);
             return false;
           }
    -      idx++;
         }
       }
       return true;
    @@ -451,7 +478,10 @@
     
       hb_vector_t vars;
       if (unlikely (!vars.alloc (plan->user_axes_location.get_population (), true)))
    +  {
    +    hb_font_destroy (font);
         return nullptr;
    +  }
     
       for (auto _ : plan->user_axes_location)
       {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -29,7 +29,14 @@
     
     struct Glyph
     {
    -  enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE, VAR_COMPOSITE };
    +  enum glyph_type_t {
    +    EMPTY,
    +    SIMPLE,
    +    COMPOSITE,
    +#ifndef HB_NO_VAR_COMPOSITES
    +    VAR_COMPOSITE,
    +#endif
    +  };
     
       public:
       composite_iter_t get_composite_iterator () const
    @@ -39,15 +46,23 @@
       }
       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;
         default:        return bytes;
         }
       }
    @@ -55,27 +70,36 @@
       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;
    -    default:        return;
    +    case EMPTY:     return;
         }
       }
     
       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;
    -    default:        return;
    +    case EMPTY:     return;
         }
       }
     
       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;
    -    default:        return;
    +    case EMPTY:     return;
         }
       }
     
    @@ -181,7 +205,7 @@
                                       hb_bytes_t &dest_start,  /* IN/OUT */
                                       hb_bytes_t &dest_end /* OUT */)
       {
    -    contour_point_vector_t all_points, deltas;
    +    contour_point_vector_t all_points, points_with_deltas;
         unsigned composite_contours = 0;
         head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
         unsigned *composite_contours_p = &composite_contours;
    @@ -195,7 +219,7 @@
           composite_contours_p = nullptr;
         }
     
    -    if (!get_points (font, glyf, all_points, &deltas, head_maxp_info_p, composite_contours_p, false, false))
    +    if (!get_points (font, glyf, all_points, &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
    @@ -209,11 +233,20 @@
         }
     
         //dont compile bytes when pinned at default, just recalculate bounds
    -    if (!plan->pinned_at_default) {
    -      switch (type) {
    +    if (!plan->pinned_at_default)
    +    {
    +      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,
    -                                                                        deltas,
    +                                                                        points_with_deltas,
                                                                             dest_end))
               return false;
             break;
    @@ -223,7 +256,7 @@
                                                                          dest_end))
               return false;
             break;
    -      default:
    +      case EMPTY:
             /* set empty bytes for empty glyph
              * do not use source glyph's pointers */
             dest_start = hb_bytes_t ();
    @@ -247,7 +280,7 @@
       template 
       bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
                        contour_point_vector_t &all_points /* OUT */,
    -                   contour_point_vector_t *deltas = nullptr, /* OUT */
    +                   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,
    @@ -287,9 +320,8 @@
           break;
         case COMPOSITE:
         {
    -      /* pseudo component points for each component in composite glyph */
    -      unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ());
    -      if (unlikely (!points.resize (num_points))) return false;
    +      for (auto &item : get_composite_iterator ())
    +        if (unlikely (!item.get_points (points))) return false;
           break;
         }
     #ifndef HB_NO_VAR_COMPOSITES
    @@ -299,7 +331,7 @@
             if (unlikely (!item.get_points (points))) return false;
         }
     #endif
    -    default:
    +    case EMPTY:
           break;
         }
     
    @@ -327,17 +359,11 @@
     #endif
                            ;
           phantoms[PHANTOM_LEFT].x = h_delta;
    -      phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
    +      phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
           phantoms[PHANTOM_TOP].y = v_orig;
           phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
         }
     
    -    if (deltas != nullptr && depth == 0 && type == COMPOSITE)
    -    {
    -      if (unlikely (!deltas->resize (points.length))) return false;
    -      deltas->copy_vector (points);
    -    }
    -
     #ifndef HB_NO_VAR
         glyf_accelerator.gvar->apply_deltas_to_points (gid,
                                                        coords,
    @@ -346,13 +372,10 @@
     
         // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
         // with child glyphs' points
    -    if (deltas != nullptr && depth == 0 && type == COMPOSITE)
    +    if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
         {
    -      for (unsigned i = 0 ; i < points.length; i++)
    -      {
    -        deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x;
    -        deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y;
    -      }
    +      if (unlikely (!points_with_deltas->resize (points.length))) return false;
    +      points_with_deltas->copy_vector (points);
         }
     
         switch (type) {
    @@ -373,7 +396,7 @@
                                            .get_points (font,
                                                         glyf_accelerator,
                                                         comp_points,
    -                                                    deltas,
    +                                                    points_with_deltas,
                                                         head_maxp_info,
                                                         composite_contours,
                                                         shift_points_hori,
    @@ -389,11 +412,12 @@
               for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
                 phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
     
    -        /* Apply component transformation & translation */
    -        item.transform_points (comp_points);
    +        float matrix[4];
    +        contour_point_t default_trans;
    +        item.get_transformation (matrix, default_trans);
     
    -        /* Apply translation from gvar */
    -        comp_points.translate (points[comp_index]);
    +        /* Apply component transformation & translation (with deltas applied) */
    +        item.transform_points (comp_points, matrix, points[comp_index]);
     
             if (item.is_anchored ())
             {
    @@ -433,7 +457,8 @@
           hb_array_t points_left = points.as_array ();
           for (auto &item : get_var_composite_iterator ())
           {
    -        hb_array_t record_points = points_left.sub_array (0, item.get_num_points ());
    +        unsigned item_num_points = item.get_num_points ();
    +        hb_array_t record_points = points_left.sub_array (0, item_num_points);
     
             comp_points.reset ();
     
    @@ -448,7 +473,7 @@
                                            .get_points (font,
                                                         glyf_accelerator,
                                                         comp_points,
    -                                                    deltas,
    +                                                    points_with_deltas,
                                                         head_maxp_info,
                                                         nullptr,
                                                         shift_points_hori,
    @@ -472,12 +497,12 @@
             if (all_points.length > HB_GLYF_MAX_POINTS)
               return false;
     
    -        points_left += item.get_num_points ();
    +        points_left += item_num_points;
           }
           all_points.extend (phantoms);
         } break;
     #endif
    -    default:
    +    case EMPTY:
           all_points.extend (phantoms);
           break;
         }
    @@ -503,6 +528,8 @@
       }
     
       hb_bytes_t get_bytes () const { return bytes; }
    +  glyph_type_t get_type () const { return type; }
    +  const GlyphHeader *get_header () const { return header; }
     
       Glyph () : bytes (),
                  header (bytes.as ()),
    @@ -518,7 +545,9 @@
         int num_contours = header->numberOfContours;
         if (unlikely (num_contours == 0)) type = EMPTY;
         else if (num_contours > 0) type = SIMPLE;
    +#ifndef HB_NO_VAR_COMPOSITES
         else if (num_contours == -2) type = VAR_COMPOSITE;
    +#endif
         else type = COMPOSITE; /* negative numbers */
       }
     
    @@ -526,7 +555,7 @@
       hb_bytes_t bytes;
       const GlyphHeader *header;
       hb_codepoint_t gid;
    -  unsigned type;
    +  glyph_type_t type;
     };
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -26,13 +26,13 @@
     
         optional_point_t lerp (optional_point_t p, float t)
         { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
    -  } first_oncurve, first_offcurve, last_offcurve, last_offcurve2;
    +  } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;
     
       path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
       {
         font = font_;
         draw_session = &draw_session_;
    -    first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
    +    first_oncurve = first_offcurve = first_offcurve2 = last_offcurve = last_offcurve2 = optional_point_t ();
       }
     
       /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
    @@ -40,7 +40,7 @@
          * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
          * https://stackoverflow.com/a/20772557
          *
    -     * Cubic support added (incomplete). */
    +     * Cubic support added. */
       void consume_point (const contour_point_t &point)
       {
         bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
    @@ -59,7 +59,12 @@
           }
           else
           {
    -        if (first_offcurve)
    +        if (is_cubic && !first_offcurve2)
    +        {
    +          first_offcurve2 = first_offcurve;
    +          first_offcurve = p;
    +        }
    +        else if (first_offcurve)
             {
               optional_point_t mid = first_offcurve.lerp (p, .5f);
               first_oncurve = mid;
    @@ -126,16 +131,30 @@
         {
           if (first_offcurve && last_offcurve)
           {
    -        optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
    -        draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
    -                                   mid.x, mid.y);
    +        optional_point_t mid = last_offcurve.lerp (first_offcurve2 ?
    +                                                   first_offcurve2 :
    +                                                   first_offcurve, .5f);
    +        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 */
           }
    +      /* now check the rest */
     
           if (first_offcurve && first_oncurve)
    -        draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
    -                                   first_oncurve.x, first_oncurve.y);
    +      {
    +        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)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -34,6 +34,11 @@
       unsigned int length (unsigned int instruction_len) const
       { return instruction_len_offset () + 2 + instruction_len; }
     
    +  bool has_instructions_length () const
    +  {
    +    return instruction_len_offset () + 2 <= bytes.length;
    +  }
    +
       unsigned int instructions_length () const
       {
         unsigned int instruction_length_offset = instruction_len_offset ();
    @@ -94,6 +99,7 @@
       /* zero instruction length */
       void drop_hints ()
       {
    +    if (!has_instructions_length ()) return;
         GlyphHeader &glyph_header = const_cast (header);
         (HBUINT16 &) StructAtOffset (&glyph_header, instruction_len_offset ()) = 0;
       }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -18,6 +18,7 @@
       Glyph source_glyph;
       hb_bytes_t dest_start;  /* region of source_glyph to copy first */
       hb_bytes_t dest_end;    /* region of source_glyph to copy second */
    +  bool allocated;
     
       bool serialize (hb_serialize_context_t *c,
                       bool use_short_loca,
    @@ -26,7 +27,12 @@
         TRACE_SERIALIZE (this);
     
         hb_bytes_t dest_glyph = dest_start.copy (c);
    -    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
    +    hb_bytes_t end_copy = dest_end.copy (c);
    +    if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
    +      return false;
    +    }
    +
    +    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
         unsigned int pad_length = use_short_loca ? padding () : 0;
         DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
     
    @@ -40,13 +46,68 @@
     
         if (unlikely (!dest_glyph.length)) return_trace (true);
     
    -    /* update components gids */
    +    /* update components gids. */
         for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
         {
           hb_codepoint_t new_gid;
           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. */
    +      char *p = it ? (char *) &*it : nullptr;
    +      char *q = p;
    +      const char *end = dest_glyph.arrayZ + dest_glyph.length;
    +      while (it)
    +      {
    +        auto &rec = const_cast (*it);
    +        ++it;
    +
    +        q += rec.get_size ();
    +
    +        rec.lower_gid_24_to_16 ();
    +
    +        unsigned size = rec.get_size ();
    +
    +        memmove (p, &rec, size);
    +
    +        p += size;
    +      }
    +      memmove (p, q, end - q);
    +      p += end - q;
    +
    +      /* We want to shorten the glyph, but we can't do that without
    +       * updating the length in the loca table, which is already
    +       * written out :-(.  So we just fill the rest of the glyph with
    +       * harmless instructions, since that's what they will be
    +       * interpreted as.
    +       *
    +       * Should move the lowering to _populate_subset_glyphs() to
    +       * fix this issue. */
    +
    +      hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p);
    +      p += end - p;
    +      dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ);
    +
    +      // TODO: Padding; & trim serialized bytes.
    +      // TODO: Update length in loca. Ugh.
    +    }
    +#endif
     
         if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
           Glyph (dest_glyph).drop_hints ();
    @@ -60,12 +121,18 @@
       bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
                                       hb_font_t *font,
                                       const glyf_accelerator_t &glyf)
    -  { return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); }
    +  {
    +    allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
    +    return allocated;
    +  }
     
       void free_compiled_bytes ()
       {
    -    dest_start.fini ();
    -    dest_end.fini ();
    +    if (likely (allocated)) {
    +      allocated = false;
    +      dest_start.fini ();
    +      dest_end.fini ();
    +    }
       }
     
       void drop_hints_bytes ()
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -27,7 +27,7 @@
         HAVE_SKEW_Y                 = 0x0200,
         HAVE_TCENTER_X              = 0x0400,
         HAVE_TCENTER_Y              = 0x0800,
    -    GID_IS_24                   = 0x1000,
    +    GID_IS_24BIT                = 0x1000,
         AXES_HAVE_VARIATION         = 0x2000,
         RESET_UNSPECIFIED_AXES      = 0x4000,
       };
    @@ -43,7 +43,7 @@
     
         // gid
         size += 2;
    -    if (flags & GID_IS_24)              size += 1;
    +    if (flags & GID_IS_24BIT)           size += 1;
     
         if (flags & HAVE_TRANSLATE_X)       size += 2;
         if (flags & HAVE_TRANSLATE_Y)       size += 2;
    @@ -65,12 +65,20 @@
     
       hb_codepoint_t get_gid () const
       {
    -    if (flags & GID_IS_24)
    +    if (flags & GID_IS_24BIT)
           return StructAfter (numAxes);
         else
           return StructAfter (numAxes);
       }
     
    +  void set_gid (hb_codepoint_t gid)
    +  {
    +    if (flags & GID_IS_24BIT)
    +      StructAfter (numAxes) = gid;
    +    else
    +      StructAfter (numAxes) = gid;
    +  }
    +
       unsigned get_numAxes () const
       {
         return numAxes;
    @@ -145,7 +153,7 @@
                           float rotation)
       {
         // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
    -    rotation = rotation * float (M_PI);
    +    rotation = rotation * HB_PI;
         float c = cosf (rotation);
         float s = sinf (rotation);
         float other[6] = {c, s, -s, c, 0.f, 0.f};
    @@ -156,8 +164,8 @@
                         float skewX, float skewY)
       {
         // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
    -    skewX = skewX * float (M_PI);
    -    skewY = skewY * float (M_PI);
    +    skewX = skewX * HB_PI;
    +    skewY = skewY * HB_PI;
         float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
         transform (matrix, trans, other);
       }
    @@ -174,16 +182,18 @@
         float tCenterX = 0.f;
         float tCenterY = 0.f;
     
    -    if (unlikely (!points.resize (points.length + get_num_points ()))) return false;
    +    unsigned num_points = get_num_points ();
    +
    +    if (unlikely (!points.resize (points.length + num_points))) return false;
     
         unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
         unsigned axes_size = numAxes * axis_width;
     
         const F2DOT14 *q = (const F2DOT14 *) (axes_size +
    -                                          (flags & GID_IS_24 ? 3 : 2) +
    +                                          (flags & GID_IS_24BIT ? 3 : 2) +
                                               &StructAfter (numAxes));
     
    -    hb_array_t rec_points = points.as_array ().sub_array (points.length - get_num_points ());
    +    hb_array_t rec_points = points.as_array ().sub_array (points.length - num_points);
     
         unsigned count = numAxes;
         if (flags & AXES_HAVE_VARIATION)
    @@ -308,8 +318,8 @@
         bool have_variations = flags & AXES_HAVE_VARIATION;
         unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
     
    -    const HBUINT8  *p = (const HBUINT8 *)  (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
    -    const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24 ? 3 : 2));
    +    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 + numAxes) : (HBUINT8 *) (q + numAxes)));
     
    @@ -344,6 +354,13 @@
       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);
    +  }
     };
     
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -126,15 +126,15 @@
           return_trace (false);
         }
     
    -    j = (unsigned) c->last_base;
    +    unsigned idx = (unsigned) c->last_base;
     
         /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
    -    //if (!_hb_glyph_info_is_ligature (&buffer->info[j])) { return_trace (false); }
    +    //if (!_hb_glyph_info_is_ligature (&buffer->info[idx])) { return_trace (false); }
     
    -    unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[j].codepoint);
    +    unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[idx].codepoint);
         if (lig_index == NOT_COVERED)
         {
    -      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
    +      buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
           return_trace (false);
         }
     
    @@ -145,7 +145,7 @@
         unsigned int comp_count = lig_attach.rows;
         if (unlikely (!comp_count))
         {
    -      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
    +      buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
           return_trace (false);
         }
     
    @@ -154,7 +154,7 @@
          * can directly use the component index.  If not, we attach the mark
          * glyph to the last component of the ligature. */
         unsigned int comp_index;
    -    unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
    +    unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[idx]);
         unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
         unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
         if (lig_id && lig_id == mark_id && mark_comp > 0)
    @@ -162,7 +162,7 @@
         else
           comp_index = comp_count - 1;
     
    -    return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
    +    return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, idx));
       }
     
       bool subset (hb_subset_context_t *c) const
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -55,7 +55,7 @@
     
         if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
         {
    -      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
    +      for (hb_codepoint_t g : glyphs->iter())
           {
             unsigned i = cov.get_coverage (g);
             if ((this+pairSet[i]).intersects (glyphs, valueFormat))
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -28,7 +28,15 @@
         TRACE_SANITIZE (this);
         return_trace (c->check_struct (this) &&
                       coverage.sanitize (c, this) &&
    +                  /* 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
    +                   * sanitizer max ops to take this into account.
    +                   *
    +                   * Note: This check *must* be right after coverage sanitize. */
    +                  c->check_ops ((this + coverage).get_population () >> 1) &&
                       valueFormat.sanitize_value (c, this, values));
    +
       }
     
       bool intersects (const hb_set_t *glyphs) const
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -29,6 +29,9 @@
       bool intersects (const hb_set_t *glyphs) const
       { return hb_all (component, glyphs); }
     
    +  bool intersects_lig_glyph (const hb_set_t *glyphs) const
    +  { return glyphs->has(ligGlyph); }
    +
       void closure (hb_closure_context_t *c) const
       {
         if (!intersects (c->glyphs)) return;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -34,6 +34,18 @@
         ;
       }
     
    +  bool intersects_lig_glyph (const hb_set_t *glyphs) const
    +  {
    +    return
    +    + hb_iter (ligature)
    +    | hb_map (hb_add (this))
    +    | hb_map ([glyphs] (const Ligature &_) {
    +      return _.intersects_lig_glyph (glyphs) && _.intersects (glyphs);
    +    })
    +    | hb_any
    +    ;
    +  }
    +
       void closure (hb_closure_context_t *c) const
       {
         + hb_iter (ligature)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSubstFormat1.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -130,7 +130,7 @@
         + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
         | hb_filter (glyphset, hb_first)
         | hb_filter ([&] (const LigatureSet& _) {
    -      return _.intersects (&glyphset);
    +      return _.intersects_lig_glyph (&glyphset);
         }, hb_second)
         | hb_map (hb_first)
         | hb_sink (new_coverage);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat1.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -25,7 +25,15 @@
       bool sanitize (hb_sanitize_context_t *c) const
       {
         TRACE_SANITIZE (this);
    -    return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
    +    return_trace (c->check_struct (this) &&
    +                  coverage.sanitize (c, this) &&
    +                  /* 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
    +                   * sanitizer max ops to take this into account.
    +                   *
    +                   * Note: This check *must* be right after coverage sanitize. */
    +                  c->check_ops ((this + coverage).get_population () >> 1));
       }
     
       hb_codepoint_t get_mask () const
    @@ -87,6 +95,34 @@
       bool would_apply (hb_would_apply_context_t *c) const
       { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
     
    +  unsigned
    +  get_glyph_alternates (hb_codepoint_t  glyph_id,
    +                        unsigned        start_offset,
    +                        unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
    +                        hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
    +  {
    +    unsigned int index = (this+coverage).get_coverage (glyph_id);
    +    if (likely (index == NOT_COVERED))
    +    {
    +      if (alternate_count)
    +        *alternate_count = 0;
    +      return 0;
    +    }
    +
    +    if (alternate_count && *alternate_count)
    +    {
    +      hb_codepoint_t d = deltaGlyphID;
    +      hb_codepoint_t mask = get_mask ();
    +
    +      glyph_id = (glyph_id + d) & mask;
    +
    +      *alternate_glyphs = glyph_id;
    +      *alternate_count = 1;
    +    }
    +
    +    return 1;
    +  }
    +
       bool apply (hb_ot_apply_context_t *c) const
       {
         TRACE_APPLY (this);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubstFormat2.hh	2023-10-06 05:33:33.000000000 +0000
    @@ -75,6 +75,31 @@
       bool would_apply (hb_would_apply_context_t *c) const
       { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
     
    +  unsigned
    +  get_glyph_alternates (hb_codepoint_t  glyph_id,
    +                        unsigned        start_offset,
    +                        unsigned       *alternate_count  /* IN/OUT.  May be NULL. */,
    +                        hb_codepoint_t *alternate_glyphs /* OUT.     May be NULL. */) const
    +  {
    +    unsigned int index = (this+coverage).get_coverage (glyph_id);
    +    if (likely (index == NOT_COVERED))
    +    {
    +      if (alternate_count)
    +        *alternate_count = 0;
    +      return 0;
    +    }
    +
    +    if (alternate_count && *alternate_count)
    +    {
    +      glyph_id = substitute[index];
    +
    +      *alternate_glyphs = glyph_id;
    +      *alternate_count = 1;
    +    }
    +
    +    return 1;
    +  }
    +
       bool apply (hb_ot_apply_context_t *c) const
       {
         TRACE_APPLY (this);
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/UPDATING.txt openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/UPDATING.txt
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/share/native/libharfbuzz/UPDATING.txt	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/share/native/libharfbuzz/UPDATING.txt	2023-10-06 05:33:33.000000000 +0000
    @@ -81,6 +81,7 @@
       To clean up the extra spaces and tabs run the following script at
       each folder level within libharfbuzz.
     
    +  shopt -s nullglob
       for f in *.c *.h *.cc *.hh;
           do
               # replace tabs with spaces
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c openjdk-lts-11.0.21+9/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/unix/native/libawt_xawt/awt/swing_GTKEngine.c	2023-10-06 05:33:33.000000000 +0000
    @@ -331,6 +331,11 @@
     {
         jint transparency;
         gint *buffer = (gint*) (*env)->GetPrimitiveArrayCritical(env, dest, 0);
    +    if (buffer == 0) {
    +        (*env)->ExceptionClear(env);
    +        JNU_ThrowOutOfMemoryError(env, "Could not get image buffer");
    +        return -1;
    +    }
         gtk->gdk_threads_enter();
         transparency = gtk->copy_image(buffer, width, height);
         gtk->gdk_threads_leave();
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java openjdk-lts-11.0.21+9/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/classes/sun/awt/windows/WClipboard.java	2023-10-06 05:33:33.000000000 +0000
    @@ -83,13 +83,7 @@
                             translateTransferable(contents, flavor, format);
                         publishClipboardData(format, bytes);
                     } catch (IOException e) {
    -                    // Fix 4696186: don't print exception if data with
    -                    // javaJVMLocalObjectMimeType failed to serialize.
    -                    // May remove this if-check when 5078787 is fixed.
    -                    if (!(flavor.isMimeTypeEqual(DataFlavor.javaJVMLocalObjectMimeType) &&
    -                          e instanceof java.io.NotSerializableException)) {
    -                        e.printStackTrace();
    -                    }
    +                    // Cannot be translated in this format, skip
                     }
                 }
             } finally {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/classes/sun/awt/windows/WScrollPanePeer.java openjdk-lts-11.0.21+9/src/java.desktop/windows/classes/sun/awt/windows/WScrollPanePeer.java
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/classes/sun/awt/windows/WScrollPanePeer.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/classes/sun/awt/windows/WScrollPanePeer.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
      * 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,13 @@
      */
     package sun.awt.windows;
     
    -import java.awt.*;
    +import java.awt.Adjustable;
    +import java.awt.Component;
    +import java.awt.Dimension;
    +import java.awt.Insets;
    +import java.awt.Point;
    +import java.awt.ScrollPane;
    +import java.awt.ScrollPaneAdjustable;
     import java.awt.event.AdjustmentEvent;
     import java.awt.peer.ScrollPanePeer;
     
    @@ -105,7 +111,6 @@
             ScrollPane sp = (ScrollPane)target;
             Dimension vs = sp.getSize();
             setSpans(vs.width, vs.height, width, height);
    -        setInsets();
         }
     
         synchronized native void setSpans(int viewWidth, int viewHeight,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBadHardware.h openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBadHardware.h
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBadHardware.h	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/java2d/d3d/D3DBadHardware.h	2023-10-06 05:33:33.000000000 +0000
    @@ -54,6 +54,9 @@
         // All Intel Chips.
         { 0x8086, ALL_DEVICEIDS, NO_VERSION, OS_ALL },
     
    +    // Microsoft Basic Render Driver (as maybe used in VMs such as VirtualBox)
    +    { 0x1414, 0x008c, NO_VERSION, OS_ALL },
    +
         // ATI Mobility Radeon X1600, X1400, X1450, X1300, X1350
         // Reason: workaround for 6613066, 6687166
         // X1300 (four sub ids)
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/awt_DataTransferer.cpp openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/awt_DataTransferer.cpp
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/awt_DataTransferer.cpp	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/awt_DataTransferer.cpp	2023-10-06 05:33:33.000000000 +0000
    @@ -163,6 +163,10 @@
     
         LOGPALETTE* pLogPalette =
             (LOGPALETTE*)env->GetPrimitiveArrayCritical(paletteBytes, NULL);
    +    if (pLogPalette == NULL) {
    +        env->DeleteLocalRef(paletteBytes);
    +        return NULL;
    +    }
         PALETTEENTRY* pPalEntries = (PALETTEENTRY*)pLogPalette->palPalEntry;
     
         pLogPalette->palVersion = 0x300;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/awt_ScrollPane.cpp	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -524,6 +524,7 @@
             DTRACE_PRINTLN5("%x: WScrollPanePeer.setSpans(%d, %d, %d, %d)", self,
                 parentWidth, parentHeight, childWidth, childHeight);
             s->RecalcSizes(parentWidth, parentHeight, childWidth, childHeight);
    +        s->SetInsets(env);
             s->VerifyState();
         }
     ret:
    @@ -701,7 +702,7 @@
         gos->scrollpane = env->NewGlobalRef(self);
         gos->orient = orient;
     
    -    return static_cast(reinterpret_cast(AwtToolkit::GetInstance().SyncCall(
    +    return static_cast(reinterpret_cast(AwtToolkit::GetInstance().InvokeFunction(
             (void *(*)(void *))AwtScrollPane::_GetOffset, gos)));
         // global ref and gos are deleted in _GetOffset()
     
    @@ -718,7 +719,7 @@
     {
         TRY
     
    -    AwtToolkit::GetInstance().SyncCall(AwtScrollPane::_SetInsets,
    +    AwtToolkit::GetInstance().InvokeFunction(AwtScrollPane::_SetInsets,
             env->NewGlobalRef(self));
         // global ref is deleted in _SetInsets()
     
    @@ -742,7 +743,7 @@
         ssps->x = x;
         ssps->y = y;
     
    -    AwtToolkit::GetInstance().SyncCall(AwtScrollPane::_SetScrollPos, ssps);
    +    AwtToolkit::GetInstance().InvokeFunctionLater(AwtScrollPane::_SetScrollPos, ssps);
         // global ref and ssps are deleted in _SetScrollPos()
     
         CATCH_BAD_ALLOC;
    @@ -803,7 +804,7 @@
         sss->childWidth = childWidth;
         sss->childHeight = childHeight;
     
    -    AwtToolkit::GetInstance().SyncCall(AwtScrollPane::_SetSpans, sss);
    +    AwtToolkit::GetInstance().InvokeFunction(AwtScrollPane::_SetSpans, sss);
         // global ref and sss are deleted in _SetSpans
     
         CATCH_BAD_ALLOC;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	2023-10-06 05:33:33.000000000 +0000
    @@ -2876,8 +2876,10 @@
         jint* colorsPtr = NULL;
         try {
             colorsPtr = (jint *)env->GetPrimitiveArrayCritical(colors, 0);
    -        for (int i = 0; i < (sizeof indexMap)/(sizeof *indexMap) && i < colorLen; i++) {
    -            colorsPtr[i] = DesktopColor2RGB(indexMap[i]);
    +        if (colorsPtr != NULL) {
    +            for (int i = 0; i < (sizeof indexMap)/(sizeof *indexMap) && i < colorLen; i++) {
    +                colorsPtr[i] = DesktopColor2RGB(indexMap[i]);
    +            }
             }
         } catch (...) {
             if (colorsPtr != NULL) {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
    --- openjdk-lts-11.0.20.1+1/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp	2023-10-06 05:33:33.000000000 +0000
    @@ -475,10 +475,11 @@
             GdiFlush();
             // Copy the resulting pixels to our Java BufferedImage.
             pDstBits = (int *)env->GetPrimitiveArrayCritical(array, 0);
    -        BOOL transparent = FALSE;
    -        transparent = IsThemeBackgroundPartiallyTransparent(hTheme,part,state);
    -        copyDIBToBufferedImage(pDstBits, pSrcBits, transparent, w, h, stride);
    -        env->ReleasePrimitiveArrayCritical(array, pDstBits, 0);
    +        if (pDstBits != NULL) {
    +            BOOL transparent = IsThemeBackgroundPartiallyTransparent(hTheme, part, state);
    +            copyDIBToBufferedImage(pDstBits, pSrcBits, transparent, w, h, stride);
    +            env->ReleasePrimitiveArrayCritical(array, pDstBits, 0);
    +        }
         }
     
         // Delete resources.
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java openjdk-lts-11.0.21+9/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java
    --- openjdk-lts-11.0.20.1+1/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2015, 2017, 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
    @@ -44,6 +44,7 @@
     import javax.naming.CommunicationException;
     import javax.naming.ldap.InitialLdapContext;
     import javax.naming.ldap.LdapContext;
    +import javax.naming.ldap.LdapName;
     import javax.security.auth.x500.X500Principal;
     
     import com.sun.jndi.ldap.LdapReferralException;
    @@ -62,8 +63,6 @@
     
         private static final Debug debug = Debug.getInstance("certpath");
     
    -    private final static boolean DEBUG = false;
    -
         /**
          * LDAP attribute identifiers.
          */
    @@ -72,7 +71,6 @@
         private static final String CROSS_CERT = "crossCertificatePair;binary";
         private static final String CRL = "certificateRevocationList;binary";
         private static final String ARL = "authorityRevocationList;binary";
    -    private static final String DELTA_CRL = "deltaRevocationList;binary";
     
         // Constants for various empty values
         private final static String[] STRING0 = new String[0];
    @@ -113,6 +111,7 @@
          * their binary stored form.
          */
         private CertificateFactory cf;
    +
         /**
          * The JNDI directory context.
          */
    @@ -200,6 +199,49 @@
             }
         }
     
    +    private static String checkName(String name) throws CertStoreException {
    +        if (name == null) {
    +            throw new CertStoreException("Name absent");
    +        }
    +        try {
    +            if (new CompositeName(name).size() > 1) {
    +                throw new CertStoreException("Invalid name: " + name);
    +            }
    +        } catch (InvalidNameException ine) {
    +            throw new CertStoreException("Invalid name: " + name, ine);
    +        }
    +        return name;
    +    }
    +
    +    /**
    +     * Get the values for the given attribute. If the attribute is null
    +     * or does not contain any values, a zero length byte array is
    +     * returned. NOTE that it is assumed that all values are byte arrays.
    +     */
    +    private static byte[][] getAttributeValues(Attribute attr)
    +            throws NamingException {
    +        byte[][] values;
    +        if (attr == null) {
    +            values = BB0;
    +        } else {
    +            values = new byte[attr.size()][];
    +            int i = 0;
    +            NamingEnumeration enum_ = attr.getAll();
    +            while (enum_.hasMore()) {
    +                Object obj = enum_.next();
    +                if (debug != null) {
    +                    if (obj instanceof String) {
    +                        debug.println("LDAPCertStore.getAttrValues() "
    +                            + "enum.next is a string!: " + obj);
    +                    }
    +                }
    +                byte[] value = (byte[])obj;
    +                values[i++] = value;
    +            }
    +        }
    +        return values;
    +    }
    +
         /**
          * Private class encapsulating the actual LDAP operations and cache
          * handling. Use:
    @@ -218,31 +260,20 @@
          */
         private class LDAPRequest {
     
    -        private final String name;
    +        private final LdapName name;
             private Map valueMap;
             private final List requestedAttributes;
     
             LDAPRequest(String name) throws CertStoreException {
    -            this.name = checkName(name);
    -            requestedAttributes = new ArrayList<>(5);
    -        }
    -
    -        private String checkName(String name) throws CertStoreException {
    -            if (name == null) {
    -                throw new CertStoreException("Name absent");
    -            }
                 try {
    -                if (new CompositeName(name).size() > 1) {
    -                    throw new CertStoreException("Invalid name: " + name);
    -                }
    +                // Convert DN to an LdapName so that it is not treated as a
    +                // composite name by JNDI. In JNDI, using a string name is
    +                // equivalent to calling new CompositeName(stringName).
    +                this.name = new LdapName(name);
                 } catch (InvalidNameException ine) {
                     throw new CertStoreException("Invalid name: " + name, ine);
                 }
    -            return name;
    -        }
    -
    -        String getName() {
    -            return name;
    +            requestedAttributes = new ArrayList<>(5);
             }
     
             void addRequestedAttribute(String attrId) {
    @@ -260,9 +291,9 @@
              * @throws NamingException      if a naming exception occurs
              */
             byte[][] getValues(String attrId) throws NamingException {
    -            if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) {
    -                System.out.println("Cache hits: " + cacheHits + "; misses: "
    -                        + cacheMisses);
    +            if (debug != null && Debug.isVerbose() && ((cacheHits + cacheMisses) % 50 == 0)) {
    +                debug.println("LDAPRequest Cache hits: " + cacheHits +
    +                    "; misses: " + cacheMisses);
                 }
                 String cacheKey = name + "|" + attrId;
                 byte[][] values = valueCache.get(cacheKey);
    @@ -294,11 +325,11 @@
                 if (valueMap != null) {
                     return valueMap;
                 }
    -            if (DEBUG) {
    -                System.out.println("Request: " + name + ":" + requestedAttributes);
    +            if (debug != null && Debug.isVerbose()) {
    +                debug.println("LDAPRequest: " + name + ":" + requestedAttributes);
                     requests++;
                     if (requests % 5 == 0) {
    -                    System.out.println("LDAP requests: " + requests);
    +                    debug.println("LDAP requests: " + requests);
                     }
                 }
                 valueMap = new HashMap<>(8);
    @@ -325,6 +356,9 @@
                             if (newDn != null && newDn.charAt(0) == '/') {
                                 newDn = newDn.substring(1);
                             }
    +                        // In JNDI, it is not possible to use an LdapName for
    +                        // the referral DN, so we must validate the syntax of
    +                        // the string DN.
                             checkName(newDn);
                         } catch (Exception e) {
                             throw new NamingException("Cannot follow referral to "
    @@ -369,36 +403,6 @@
                 String cacheKey = name + "|" + attrId;
                 valueCache.put(cacheKey, values);
             }
    -
    -        /**
    -         * Get the values for the given attribute. If the attribute is null
    -         * or does not contain any values, a zero length byte array is
    -         * returned. NOTE that it is assumed that all values are byte arrays.
    -         */
    -        private byte[][] getAttributeValues(Attribute attr)
    -                throws NamingException {
    -            byte[][] values;
    -            if (attr == null) {
    -                values = BB0;
    -            } else {
    -                values = new byte[attr.size()][];
    -                int i = 0;
    -                NamingEnumeration enum_ = attr.getAll();
    -                while (enum_.hasMore()) {
    -                    Object obj = enum_.next();
    -                    if (debug != null) {
    -                        if (obj instanceof String) {
    -                            debug.println("LDAPCertStore.getAttrValues() "
    -                                + "enum.next is a string!: " + obj);
    -                        }
    -                    }
    -                    byte[] value = (byte[])obj;
    -                    values[i++] = value;
    -                }
    -            }
    -            return values;
    -        }
    -
         }
     
         /*
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java openjdk-lts-11.0.21+9/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java
    --- openjdk-lts-11.0.20.1+1/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java	2023-10-06 05:33:33.000000000 +0000
    @@ -34,6 +34,7 @@
     import java.net.URL;
     import java.util.Base64;
     import java.util.LinkedList;
    +import java.util.List;
     import java.util.Objects;
     import java.util.WeakHashMap;
     import java.net.http.HttpHeaders;
    @@ -261,23 +262,21 @@
     
             boolean proxy = status == PROXY_UNAUTHORIZED;
             String authname = proxy ? "Proxy-Authenticate" : "WWW-Authenticate";
    -        String authval = hdrs.firstValue(authname).orElse(null);
    -        if (authval == null) {
    -            if (exchange.client().authenticator().isPresent()) {
    -                throw new IOException(authname + " header missing for response code " + status);
    -            } else {
    -                // No authenticator? let the caller deal with this.
    -                return null;
    +        List authvals = hdrs.allValues(authname);
    +        if (authvals.isEmpty() && exchange.client().authenticator().isPresent()) {
    +            throw new IOException(authname + " header missing for response code " + status);
    +        }
    +        String authval = null;
    +        for (String aval : authvals) {
    +            HeaderParser parser = new HeaderParser(aval);
    +            String scheme = parser.findKey(0);
    +            if (scheme.equalsIgnoreCase("Basic")) {
    +                authval = aval;
    +                break;
                 }
             }
    -
    -        HeaderParser parser = new HeaderParser(authval);
    -        String scheme = parser.findKey(0);
    -
    -        // TODO: Need to generalise from Basic only. Delegate to a provider class etc.
    -
    -        if (!scheme.equalsIgnoreCase("Basic")) {
    -            return null;   // error gets returned to app
    +        if (authval == null) {
    +            return null;
             }
     
             if (proxy) {
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/org/ietf/jgss/Oid.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 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
    @@ -65,7 +65,7 @@
         public Oid(String strOid) throws GSSException {
     
             try {
    -            oid = new ObjectIdentifier(strOid);
    +            oid = ObjectIdentifier.of(strOid);
                 derEncoding = null;
             } catch (Exception e) {
                 throw new GSSException(GSSException.FAILURE,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java	2023-10-06 05:33:33.000000000 +0000
    @@ -132,6 +132,11 @@
                             "fallback to other scheme if allowed. Reason:");
                     e.printStackTrace();
                 }
    +            try {
    +                disposeContext();
    +            } catch (Exception ex) {
    +                //dispose context silently
    +            }
                 IOException ioe = new IOException("Negotiate support not initiated");
                 ioe.initCause(e);
                 throw ioe;
    @@ -156,6 +161,9 @@
         @Override
         public byte[] nextToken(byte[] token) throws IOException {
             try {
    +            if (context == null) {
    +                throw new IOException("Negotiate support cannot continue. Context is invalidated");
    +            }
                 return context.initSecContext(token, 0, token.length);
             } catch (GSSException e) {
                 if (DEBUG) {
    @@ -167,4 +175,26 @@
                 throw ioe;
             }
         }
    +
    +    /**
    +     * Releases any system resources and cryptographic information stored in
    +     * the context object and invalidates the context.
    +     *
    +     * @throws IOException containing a reason of failure in the cause
    +     */
    +    @Override
    +    public void disposeContext() throws IOException {
    +        try {
    +            if (context != null) {
    +                context.dispose();
    +            }
    +        } catch (GSSException e) {
    +            if (DEBUG) {
    +                System.out.println("Cannot release resources. Reason:");
    +                e.printStackTrace();
    +            }
    +            throw new IOException("Cannot release resources", e);
    +        };
    +        context = null;
    +    }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/GSSContextImpl.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 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
    @@ -241,7 +241,7 @@
                     mechCtxt.setChannelBinding(channelBindings);
                     mechCtxt.requestDelegPolicy(reqDelegPolicyState);
     
    -                objId = new ObjectIdentifier(mechOid.toString());
    +                objId = ObjectIdentifier.of(mechOid.toString());
     
                     currentState = IN_PROGRESS;
                     firstToken = true;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/GSSNameImpl.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 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
    @@ -412,7 +412,7 @@
             ObjectIdentifier oid = null;
     
             try {
    -            oid = new ObjectIdentifier
    +            oid = ObjectIdentifier.of
                     (mechElement.getMechanism().toString());
             } catch (IOException e) {
                 throw new GSSExceptionImpl(GSSException.FAILURE,
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Token.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2000, 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
    @@ -77,7 +77,7 @@
     
         static {
             try {
    -            OID = new ObjectIdentifier(Krb5MechFactory.
    +            OID = ObjectIdentifier.of(Krb5MechFactory.
                                            GSS_KRB5_MECH_OID.toString());
             } catch (IOException ioe) {
               // should not happen
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoToken.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 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
    @@ -68,7 +68,7 @@
     
         static {
             try {
    -            OID = new ObjectIdentifier(SpNegoMechFactory.
    +            OID = ObjectIdentifier.of(SpNegoMechFactory.
                                            GSS_SPNEGO_MECH_OID.toString());
             } catch (IOException ioe) {
               // should not happen
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 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
    @@ -130,7 +130,7 @@
                     DerOutputStream dout = new DerOutputStream();
                     Oid mech = cStub.getMech();
                     try {
    -                    dout.putOID(new ObjectIdentifier(mech.toString()));
    +                    dout.putOID(ObjectIdentifier.of(mech.toString()));
                     } catch (IOException e) {
                         throw new GSSExceptionImpl(GSSException.FAILURE, e);
                     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2005, 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
    @@ -160,7 +160,7 @@
                     SunNativeProvider.debug("Precomputed mechToken length: " +
                                              mechTokenLen);
                     GSSHeader gssHeader = new GSSHeader
    -                    (new ObjectIdentifier(cStub.getMech().toString()),
    +                    (ObjectIdentifier.of(cStub.getMech().toString()),
                          mechTokenLen);
                     ByteArrayOutputStream baos = new ByteArrayOutputStream(600);
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java	2023-10-06 05:33:33.000000000 +0000
    @@ -248,6 +248,7 @@
         public static final int KDC_ERR_KEY_EXPIRED          = 23;   //Password has expired - change password to reset
         public static final int KDC_ERR_PREAUTH_FAILED       = 24;   //Pre-authentication information was invalid
         public static final int KDC_ERR_PREAUTH_REQUIRED     = 25;   //Additional pre-authentication required
    +    public static final int KDC_ERR_SVC_UNAVAILABLE      = 29;   //A service is not available
         public static final int KRB_AP_ERR_BAD_INTEGRITY     = 31;   //Integrity check on decrypted field failed
         public static final int KRB_AP_ERR_TKT_EXPIRED       = 32;   //Ticket expired
         public static final int KRB_AP_ERR_TKT_NYV           = 33;   //Ticket not yet valid
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java
    --- openjdk-lts-11.0.20.1+1/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java	2023-10-06 05:33:33.000000000 +0000
    @@ -257,9 +257,14 @@
                 } catch (Exception e) {
                     // OK
                 }
    -            if (ke != null && ke.getErrorCode() ==
    +            if (ke != null) {
    +                if (ke.getErrorCode() ==
                         Krb5.KRB_ERR_RESPONSE_TOO_BIG) {
    -                ibuf = send(obuf, tempKdc, true);
    +                    ibuf = send(obuf, tempKdc, true);
    +                } else if (ke.getErrorCode() ==
    +                        Krb5.KDC_ERR_SVC_UNAVAILABLE) {
    +                    throw new KrbException("A service is not available");
    +                }
                 }
                 KdcAccessibility.removeBad(tempKdc);
                 return ibuf;
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java	2023-10-06 05:33:33.000000000 +0000
    @@ -29,14 +29,17 @@
      */
     public abstract class AccessFlags {
     
    -    private int access_flags;
    +    /**
    +     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
    +     */
    +    @java.lang.Deprecated
    +    protected int access_flags; // TODO not used externally at present
     
         public AccessFlags() {
         }
     
         /**
    -     * @param a
    -     *            inital access flags
    +     * @param a initial access flags
          */
         public AccessFlags(final int a) {
             access_flags = a;
    @@ -56,163 +59,159 @@
             return access_flags;
         }
     
    -    /**
    -     * Set access flags aka "modifiers".
    -     *
    -     * @param access_flags
    -     *            Access flags of the object.
    -     */
    -    public final void setAccessFlags(final int access_flags) {
    -        this.access_flags = access_flags;
    -    }
    -
    -    /**
    -     * Set access flags aka "modifiers".
    -     *
    -     * @param access_flags
    -     *            Access flags of the object.
    -     */
    -    public final void setModifiers(final int access_flags) {
    -        setAccessFlags(access_flags);
    -    }
    -
    -    private void setFlag(final int flag, final boolean set) {
    -        if ((access_flags & flag) != 0) { // Flag is set already
    -            if (!set) {
    -                access_flags ^= flag;
    -            }
    -        } else { // Flag not set
    -            if (set) {
    -                access_flags |= flag;
    -            }
    -        }
    -    }
    -
    -    public final void isPublic(final boolean flag) {
    -        setFlag(Const.ACC_PUBLIC, flag);
    -    }
    -
    -    public final boolean isPublic() {
    -        return (access_flags & Const.ACC_PUBLIC) != 0;
    +    public final boolean isAbstract() {
    +        return (access_flags & Const.ACC_ABSTRACT) != 0;
         }
     
    -    public final void isPrivate(final boolean flag) {
    -        setFlag(Const.ACC_PRIVATE, flag);
    +    public final void isAbstract(final boolean flag) {
    +        setFlag(Const.ACC_ABSTRACT, flag);
         }
     
    -    public final boolean isPrivate() {
    -        return (access_flags & Const.ACC_PRIVATE) != 0;
    +    public final boolean isAnnotation() {
    +        return (access_flags & Const.ACC_ANNOTATION) != 0;
         }
     
    -    public final void isProtected(final boolean flag) {
    -        setFlag(Const.ACC_PROTECTED, flag);
    +    public final void isAnnotation(final boolean flag) {
    +        setFlag(Const.ACC_ANNOTATION, flag);
         }
     
    -    public final boolean isProtected() {
    -        return (access_flags & Const.ACC_PROTECTED) != 0;
    +    public final boolean isEnum() {
    +        return (access_flags & Const.ACC_ENUM) != 0;
         }
     
    -    public final void isStatic(final boolean flag) {
    -        setFlag(Const.ACC_STATIC, flag);
    +    public final void isEnum(final boolean flag) {
    +        setFlag(Const.ACC_ENUM, flag);
         }
     
    -    public final boolean isStatic() {
    -        return (access_flags & Const.ACC_STATIC) != 0;
    +    public final boolean isFinal() {
    +        return (access_flags & Const.ACC_FINAL) != 0;
         }
     
         public final void isFinal(final boolean flag) {
             setFlag(Const.ACC_FINAL, flag);
         }
     
    -    public final boolean isFinal() {
    -        return (access_flags & Const.ACC_FINAL) != 0;
    +    public final boolean isInterface() {
    +        return (access_flags & Const.ACC_INTERFACE) != 0;
         }
     
    -    public final void isSynchronized(final boolean flag) {
    -        setFlag(Const.ACC_SYNCHRONIZED, flag);
    +    public final void isInterface(final boolean flag) {
    +        setFlag(Const.ACC_INTERFACE, flag);
         }
     
    -    public final boolean isSynchronized() {
    -        return (access_flags & Const.ACC_SYNCHRONIZED) != 0;
    +    public final boolean isNative() {
    +        return (access_flags & Const.ACC_NATIVE) != 0;
         }
     
    -    public final void isVolatile(final boolean flag) {
    -        setFlag(Const.ACC_VOLATILE, flag);
    +    public final void isNative(final boolean flag) {
    +        setFlag(Const.ACC_NATIVE, flag);
         }
     
    -    public final boolean isVolatile() {
    -        return (access_flags & Const.ACC_VOLATILE) != 0;
    +    public final boolean isPrivate() {
    +        return (access_flags & Const.ACC_PRIVATE) != 0;
         }
     
    -    public final void isTransient(final boolean flag) {
    -        setFlag(Const.ACC_TRANSIENT, flag);
    +    public final void isPrivate(final boolean flag) {
    +        setFlag(Const.ACC_PRIVATE, flag);
         }
     
    -    public final boolean isTransient() {
    -        return (access_flags & Const.ACC_TRANSIENT) != 0;
    +    public final boolean isProtected() {
    +        return (access_flags & Const.ACC_PROTECTED) != 0;
         }
     
    -    public final void isNative(final boolean flag) {
    -        setFlag(Const.ACC_NATIVE, flag);
    +    public final void isProtected(final boolean flag) {
    +        setFlag(Const.ACC_PROTECTED, flag);
         }
     
    -    public final boolean isNative() {
    -        return (access_flags & Const.ACC_NATIVE) != 0;
    +    public final boolean isPublic() {
    +        return (access_flags & Const.ACC_PUBLIC) != 0;
         }
     
    -    public final void isInterface(final boolean flag) {
    -        setFlag(Const.ACC_INTERFACE, flag);
    +    public final void isPublic(final boolean flag) {
    +        setFlag(Const.ACC_PUBLIC, flag);
         }
     
    -    public final boolean isInterface() {
    -        return (access_flags & Const.ACC_INTERFACE) != 0;
    +    public final boolean isStatic() {
    +        return (access_flags & Const.ACC_STATIC) != 0;
         }
     
    -    public final void isAbstract(final boolean flag) {
    -        setFlag(Const.ACC_ABSTRACT, flag);
    +    public final void isStatic(final boolean flag) {
    +        setFlag(Const.ACC_STATIC, flag);
         }
     
    -    public final boolean isAbstract() {
    -        return (access_flags & Const.ACC_ABSTRACT) != 0;
    +    public final boolean isStrictfp() {
    +        return (access_flags & Const.ACC_STRICT) != 0;
         }
     
         public final void isStrictfp(final boolean flag) {
             setFlag(Const.ACC_STRICT, flag);
         }
     
    -    public final boolean isStrictfp() {
    -        return (access_flags & Const.ACC_STRICT) != 0;
    +    public final boolean isSynchronized() {
    +        return (access_flags & Const.ACC_SYNCHRONIZED) != 0;
         }
     
    -    public final void isSynthetic(final boolean flag) {
    -        setFlag(Const.ACC_SYNTHETIC, flag);
    +    public final void isSynchronized(final boolean flag) {
    +        setFlag(Const.ACC_SYNCHRONIZED, flag);
         }
     
         public final boolean isSynthetic() {
             return (access_flags & Const.ACC_SYNTHETIC) != 0;
         }
     
    -    public final void isAnnotation(final boolean flag) {
    -        setFlag(Const.ACC_ANNOTATION, flag);
    +    public final void isSynthetic(final boolean flag) {
    +        setFlag(Const.ACC_SYNTHETIC, flag);
         }
     
    -    public final boolean isAnnotation() {
    -        return (access_flags & Const.ACC_ANNOTATION) != 0;
    +    public final boolean isTransient() {
    +        return (access_flags & Const.ACC_TRANSIENT) != 0;
         }
     
    -    public final void isEnum(final boolean flag) {
    -        setFlag(Const.ACC_ENUM, flag);
    +    public final void isTransient(final boolean flag) {
    +        setFlag(Const.ACC_TRANSIENT, flag);
         }
     
    -    public final boolean isEnum() {
    -        return (access_flags & Const.ACC_ENUM) != 0;
    +    public final boolean isVarArgs() {
    +        return (access_flags & Const.ACC_VARARGS) != 0;
         }
     
         public final void isVarArgs(final boolean flag) {
             setFlag(Const.ACC_VARARGS, flag);
         }
     
    -    public final boolean isVarArgs() {
    -        return (access_flags & Const.ACC_VARARGS) != 0;
    +    public final boolean isVolatile() {
    +        return (access_flags & Const.ACC_VOLATILE) != 0;
    +    }
    +
    +    public final void isVolatile(final boolean flag) {
    +        setFlag(Const.ACC_VOLATILE, flag);
    +    }
    +
    +    /**
    +     * Set access flags aka "modifiers".
    +     *
    +     * @param accessFlags Access flags of the object.
    +     */
    +    public final void setAccessFlags(final int accessFlags) {
    +        this.access_flags = accessFlags;
    +    }
    +
    +    private void setFlag(final int flag, final boolean set) {
    +        if ((access_flags & flag) != 0) { // Flag is set already
    +            if (!set) {
    +                access_flags ^= flag;
    +            }
    +        } else if (set) {
    +            access_flags |= flag;
    +        }
    +    }
    +
    +    /**
    +     * Set access flags aka "modifiers".
    +     *
    +     * @param accessFlags Access flags of the object.
    +     */
    +    public final void setModifiers(final int accessFlags) {
    +        setAccessFlags(accessFlags);
         }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationDefault.java	2023-10-06 05:33:33.000000000 +0000
    @@ -28,7 +28,7 @@
     import com.sun.org.apache.bcel.internal.Const;
     
     /**
    - * Represents the default value of a annotation for a method info
    + * Represents the default value of a annotation for a method info.
      *
      * @since 6.0
      */
    @@ -37,31 +37,30 @@
         private ElementValue defaultValue;
     
         /**
    -     * @param name_index    Index pointing to the name Code
    -     * @param length        Content length in bytes
    -     * @param input         Input stream
    -     * @param constant_pool Array of constants
    +     * @param nameIndex Index pointing to the name Code
    +     * @param length Content length in bytes
    +     * @param input Input stream
    +     * @param constantPool Array of constants
          */
    -    AnnotationDefault(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException {
    -        this(name_index, length, (ElementValue) null, constant_pool);
    -        defaultValue = ElementValue.readElementValue(input, constant_pool);
    +    AnnotationDefault(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
    +        this(nameIndex, length, (ElementValue) null, constantPool);
    +        defaultValue = ElementValue.readElementValue(input, constantPool);
         }
     
         /**
    -     * @param name_index    Index pointing to the name Code
    -     * @param length        Content length in bytes
    -     * @param defaultValue  the annotation's default value
    -     * @param constant_pool Array of constants
    +     * @param nameIndex Index pointing to the name Code
    +     * @param length Content length in bytes
    +     * @param defaultValue the annotation's default value
    +     * @param constantPool Array of constants
          */
    -    public AnnotationDefault(final int name_index, final int length, final ElementValue defaultValue, final ConstantPool constant_pool) {
    -        super(Const.ATTR_ANNOTATION_DEFAULT, name_index, length, constant_pool);
    +    public AnnotationDefault(final int nameIndex, final int length, final ElementValue defaultValue, final ConstantPool constantPool) {
    +        super(Const.ATTR_ANNOTATION_DEFAULT, nameIndex, length, constantPool);
             this.defaultValue = defaultValue;
         }
     
         /**
    -     * Called by objects that are traversing the nodes of the tree implicitely
    -     * defined by the contents of a Java class. I.e., the hierarchy of methods,
    -     * fields, attributes, etc. spawns a tree of objects.
    +     * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
    +     * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
          *
          * @param v Visitor object
          */
    @@ -70,11 +69,15 @@
             v.visitAnnotationDefault(this);
         }
     
    -    /**
    -     * @param defaultValue the default value of this methodinfo's annotation
    -     */
    -    public final void setDefaultValue(final ElementValue defaultValue) {
    -        this.defaultValue = defaultValue;
    +    @Override
    +    public Attribute copy(final ConstantPool constantPool) {
    +        return (Attribute) clone();
    +    }
    +
    +    @Override
    +    public final void dump(final DataOutputStream dos) throws IOException {
    +        super.dump(dos);
    +        defaultValue.dump(dos);
         }
     
         /**
    @@ -84,14 +87,10 @@
             return defaultValue;
         }
     
    -    @Override
    -    public Attribute copy(final ConstantPool _constant_pool) {
    -        return (Attribute) clone();
    -    }
    -
    -    @Override
    -    public final void dump(final DataOutputStream dos) throws IOException {
    -        super.dump(dos);
    -        defaultValue.dump(dos);
    +    /**
    +     * @param defaultValue the default value of this methodinfo's annotation
    +     */
    +    public final void setDefaultValue(final ElementValue defaultValue) {
    +        this.defaultValue = defaultValue;
         }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationElementValue.java	2023-10-06 05:33:33.000000000 +0000
    @@ -27,43 +27,35 @@
     /**
      * @since 6.0
      */
    -public class AnnotationElementValue extends ElementValue
    -{
    -        // For annotation element values, this is the annotation
    -        private final AnnotationEntry annotationEntry;
    +public class AnnotationElementValue extends ElementValue {
    +    // For annotation element values, this is the annotation
    +    private final AnnotationEntry annotationEntry;
     
    -        public AnnotationElementValue(final int type, final AnnotationEntry annotationEntry,
    -                        final ConstantPool cpool)
    -        {
    -                super(type, cpool);
    -                if (type != ANNOTATION) {
    -                    throw new IllegalArgumentException(
    -                                    "Only element values of type annotation can be built with this ctor - type specified: " + type);
    -                }
    -                this.annotationEntry = annotationEntry;
    +    public AnnotationElementValue(final int type, final AnnotationEntry annotationEntry, final ConstantPool cpool) {
    +        super(type, cpool);
    +        if (type != ANNOTATION) {
    +            throw new ClassFormatException("Only element values of type annotation can be built with this ctor - type specified: " + type);
             }
    +        this.annotationEntry = annotationEntry;
    +    }
     
    -        @Override
    -        public void dump(final DataOutputStream dos) throws IOException
    -        {
    -                dos.writeByte(super.getType()); // u1 type of value (ANNOTATION == '@')
    -                annotationEntry.dump(dos);
    -        }
    +    @Override
    +    public void dump(final DataOutputStream dos) throws IOException {
    +        dos.writeByte(super.getType()); // u1 type of value (ANNOTATION == '@')
    +        annotationEntry.dump(dos);
    +    }
     
    -        @Override
    -        public String stringifyValue()
    -        {
    -                return annotationEntry.toString();
    -        }
    +    public AnnotationEntry getAnnotationEntry() {
    +        return annotationEntry;
    +    }
     
    -        @Override
    -        public String toString()
    -        {
    -                return stringifyValue();
    -        }
    +    @Override
    +    public String stringifyValue() {
    +        return annotationEntry.toString();
    +    }
     
    -        public AnnotationEntry getAnnotationEntry()
    -        {
    -                return annotationEntry;
    -        }
    +    @Override
    +    public String toString() {
    +        return stringifyValue();
    +    }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AnnotationEntry.java	2023-10-06 05:33:33.000000000 +0000
    @@ -25,66 +25,60 @@
     import java.io.DataOutputStream;
     import java.io.IOException;
     import java.util.ArrayList;
    -import java.util.Collections;
     import java.util.List;
    -
    -import com.sun.org.apache.bcel.internal.Const;
    +import java.util.stream.Stream;
     
     /**
    - * represents one annotation in the annotation table
    + * Represents one annotation in the annotation table
      *
      * @since 6.0
      */
     public class AnnotationEntry implements Node {
     
    -    private final int typeIndex;
    -    private final ConstantPool constantPool;
    -    private final boolean isRuntimeVisible;
    +    public static final AnnotationEntry[] EMPTY_ARRAY = {};
     
    -    private List elementValuePairs;
    +    public static AnnotationEntry[] createAnnotationEntries(final Attribute[] attrs) {
    +        // Find attributes that contain annotation data
    +        return Stream.of(attrs).filter(Annotations.class::isInstance).flatMap(e -> Stream.of(((Annotations) e).getAnnotationEntries()))
    +            .toArray(AnnotationEntry[]::new);
    +    }
     
    -    /*
    +    /**
          * Factory method to create an AnnotionEntry from a DataInput
          *
          * @param input
          * @param constantPool
          * @param isRuntimeVisible
          * @return the entry
    -     * @throws IOException
    +     * @throws IOException if an I/O error occurs.
          */
    -    public static AnnotationEntry read(final DataInput input, final ConstantPool constant_pool, final boolean isRuntimeVisible) throws IOException {
    -
    -        final AnnotationEntry annotationEntry = new AnnotationEntry(input.readUnsignedShort(), constant_pool, isRuntimeVisible);
    -        final int num_element_value_pairs = input.readUnsignedShort();
    +    public static AnnotationEntry read(final DataInput input, final ConstantPool constantPool, final boolean isRuntimeVisible) throws IOException {
    +        final AnnotationEntry annotationEntry = new AnnotationEntry(input.readUnsignedShort(), constantPool, isRuntimeVisible);
    +        final int numElementValuePairs = input.readUnsignedShort();
             annotationEntry.elementValuePairs = new ArrayList<>();
    -        for (int i = 0; i < num_element_value_pairs; i++) {
    -            annotationEntry.elementValuePairs.add(
    -                    new ElementValuePair(input.readUnsignedShort(), ElementValue.readElementValue(input, constant_pool),
    -                    constant_pool));
    +        for (int i = 0; i < numElementValuePairs; i++) {
    +            annotationEntry.elementValuePairs
    +                .add(new ElementValuePair(input.readUnsignedShort(), ElementValue.readElementValue(input, constantPool), constantPool));
             }
             return annotationEntry;
         }
     
    -    public AnnotationEntry(final int type_index, final ConstantPool constant_pool, final boolean isRuntimeVisible) {
    -        this.typeIndex = type_index;
    -        this.constantPool = constant_pool;
    -        this.isRuntimeVisible = isRuntimeVisible;
    -    }
    +    private final int typeIndex;
     
    -    public int getTypeIndex() {
    -        return typeIndex;
    -    }
    +    private final ConstantPool constantPool;
     
    -    public ConstantPool getConstantPool() {
    -        return constantPool;
    -    }
    +    private final boolean isRuntimeVisible;
     
    -    public boolean isRuntimeVisible() {
    -        return isRuntimeVisible;
    +    private List elementValuePairs;
    +
    +    public AnnotationEntry(final int typeIndex, final ConstantPool constantPool, final boolean isRuntimeVisible) {
    +        this.typeIndex = typeIndex;
    +        this.constantPool = constantPool;
    +        this.isRuntimeVisible = isRuntimeVisible;
         }
     
         /**
    -     * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class.
    +     * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
          * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
          *
          * @param v Visitor object
    @@ -94,12 +88,24 @@
             v.visitAnnotationEntry(this);
         }
     
    +    public void addElementNameValuePair(final ElementValuePair elementNameValuePair) {
    +        elementValuePairs.add(elementNameValuePair);
    +    }
    +
    +    public void dump(final DataOutputStream dos) throws IOException {
    +        dos.writeShort(typeIndex); // u2 index of type name in cpool
    +        dos.writeShort(elementValuePairs.size()); // u2 element_value pair
    +        // count
    +        for (final ElementValuePair envp : elementValuePairs) {
    +            envp.dump(dos);
    +        }
    +    }
    +
         /**
          * @return the annotation type name
          */
         public String getAnnotationType() {
    -        final ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant(typeIndex, Const.CONSTANT_Utf8);
    -        return c.getBytes();
    +        return constantPool.getConstantUtf8(typeIndex).getBytes();
         }
     
         /**
    @@ -109,11 +115,8 @@
             return typeIndex;
         }
     
    -    /**
    -     * @return the number of element value pairs in this annotation entry
    -     */
    -    public final int getNumElementValuePairs() {
    -        return elementValuePairs.size();
    +    public ConstantPool getConstantPool() {
    +        return constantPool;
         }
     
         /**
    @@ -121,20 +124,22 @@
          */
         public ElementValuePair[] getElementValuePairs() {
             // TODO return List
    -        return elementValuePairs.toArray(new ElementValuePair[elementValuePairs.size()]);
    +        return elementValuePairs.toArray(ElementValuePair.EMPTY_ARRAY);
         }
     
    -    public void dump(final DataOutputStream dos) throws IOException {
    -        dos.writeShort(typeIndex); // u2 index of type name in cpool
    -        dos.writeShort(elementValuePairs.size()); // u2 element_value pair
    -        // count
    -        for (final ElementValuePair envp : elementValuePairs) {
    -            envp.dump(dos);
    -        }
    +    /**
    +     * @return the number of element value pairs in this annotation entry
    +     */
    +    public final int getNumElementValuePairs() {
    +        return elementValuePairs.size();
         }
     
    -    public void addElementNameValuePair(final ElementValuePair elementNameValuePair) {
    -        elementValuePairs.add(elementNameValuePair);
    +    public int getTypeIndex() {
    +        return typeIndex;
    +    }
    +
    +    public boolean isRuntimeVisible() {
    +        return isRuntimeVisible;
         }
     
         public String toShortString() {
    @@ -146,7 +151,10 @@
                 result.append("(");
                 for (final ElementValuePair element : evPairs) {
                     result.append(element.toShortString());
    +                result.append(", ");
                 }
    +            // remove last ", "
    +            result.setLength(result.length() - 2);
                 result.append(")");
             }
             return result.toString();
    @@ -156,16 +164,4 @@
         public String toString() {
             return toShortString();
         }
    -
    -    public static AnnotationEntry[] createAnnotationEntries(final Attribute[] attrs) {
    -        // Find attributes that contain annotation data
    -        final List accumulatedAnnotations = new ArrayList<>(attrs.length);
    -        for (final Attribute attribute : attrs) {
    -            if (attribute instanceof Annotations) {
    -                final Annotations runtimeAnnotations = (Annotations) attribute;
    -                Collections.addAll(accumulatedAnnotations, runtimeAnnotations.getAnnotationEntries());
    -            }
    -        }
    -        return accumulatedAnnotations.toArray(new AnnotationEntry[accumulatedAnnotations.size()]);
    -    }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Annotations.java	2023-10-06 05:33:33.000000000 +0000
    @@ -24,40 +24,30 @@
     import java.io.DataInput;
     import java.io.DataOutputStream;
     import java.io.IOException;
    +import java.util.Iterator;
    +import java.util.stream.Stream;
    +
    +import com.sun.org.apache.bcel.internal.Const;
     
     /**
      * base class for annotations
      *
      * @since 6.0
      */
    -public abstract class Annotations extends Attribute {
    +public abstract class Annotations extends Attribute implements Iterable {
     
         private AnnotationEntry[] annotationTable;
         private final boolean isRuntimeVisible;
     
         /**
    -     * @param annotation_type the subclass type of the annotation
    -     * @param name_index Index pointing to the name Code
    -     * @param length Content length in bytes
    -     * @param input Input stream
    -     * @param constant_pool Array of constants
    -     */
    -    Annotations(final byte annotation_type, final int name_index, final int length, final DataInput input,
    -            final ConstantPool constant_pool, final boolean isRuntimeVisible) throws IOException {
    -        this(annotation_type, name_index, length, (AnnotationEntry[]) null, constant_pool, isRuntimeVisible);
    -        final int annotation_table_length = input.readUnsignedShort();
    -        annotationTable = new AnnotationEntry[annotation_table_length];
    -        for (int i = 0; i < annotation_table_length; i++) {
    -            annotationTable[i] = AnnotationEntry.read(input, constant_pool, isRuntimeVisible);
    -        }
    -    }
    -
    -    /**
    -     * @param annotationType the subclass type of the annotation
    -     * @param nameIndex Index pointing to the name Code
    -     * @param length Content length in bytes
    -     * @param annotationTable the actual annotations
    -     * @param constantPool Array of constants
    +     * Constructs an instance.
    +     *
    +     * @param annotationType   the subclass type of the annotation
    +     * @param nameIndex        Index pointing to the name Code
    +     * @param length           Content length in bytes
    +     * @param annotationTable  the actual annotations
    +     * @param constantPool     Array of constants
    +     * @param isRuntimeVisible whether this Annotation visible at runtime
          */
         public Annotations(final byte annotationType, final int nameIndex, final int length, final AnnotationEntry[] annotationTable,
                 final ConstantPool constantPool, final boolean isRuntimeVisible) {
    @@ -67,8 +57,30 @@
         }
     
         /**
    -     * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class.
    -     * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
    +     * Constructs an instance.
    +     *
    +     * @param annotationType   the subclass type of the annotation
    +     * @param nameIndex        Index pointing to the name Code
    +     * @param length           Content length in bytes
    +     * @param input            Input stream
    +     * @param constantPool     Array of constants
    +     * @param isRuntimeVisible whether this Annotation visible at runtime
    +     * @throws IOException if an I/O error occurs.
    +     */
    +    Annotations(final byte annotationType, final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool,
    +            final boolean isRuntimeVisible) throws IOException {
    +        this(annotationType, nameIndex, length, (AnnotationEntry[]) null, constantPool, isRuntimeVisible);
    +        final int annotationTableLength = input.readUnsignedShort();
    +        annotationTable = new AnnotationEntry[annotationTableLength];
    +        for (int i = 0; i < annotationTableLength; i++) {
    +            annotationTable[i] = AnnotationEntry.read(input, constantPool, isRuntimeVisible);
    +        }
    +    }
    +
    +    /**
    +     * Called by objects that are traversing the nodes of the tree implicitly
    +     * defined by the contents of a Java class. I.e., the hierarchy of methods,
    +     * fields, attributes, etc. spawns a tree of objects.
          *
          * @param v Visitor object
          */
    @@ -77,21 +89,22 @@
             v.visitAnnotation(this);
         }
     
    -    /**
    -     * @param annotationTable the entries to set in this annotation
    -     */
    -    public final void setAnnotationTable(final AnnotationEntry[] annotationTable) {
    -        this.annotationTable = annotationTable;
    +    @Override
    +    public Attribute copy(final ConstantPool constantPool) {
    +        // TODO Auto-generated method stub
    +        return null;
         }
     
         /**
    -     * returns the array of annotation entries in this annotation
    +     * Gets the array of annotation entries in this annotation
          */
         public AnnotationEntry[] getAnnotationEntries() {
             return annotationTable;
         }
     
         /**
    +     * Gets the number of annotation entries in this annotation.
    +     *
          * @return the number of annotation entries in this annotation
          */
         public final int getNumAnnotations() {
    @@ -105,6 +118,38 @@
             return isRuntimeVisible;
         }
     
    +    @Override
    +    public Iterator iterator() {
    +        return Stream.of(annotationTable).iterator();
    +    }
    +
    +    /**
    +     * Sets the entries to set in this annotation.
    +     *
    +     * @param annotationTable the entries to set in this annotation
    +     */
    +    public final void setAnnotationTable(final AnnotationEntry[] annotationTable) {
    +        this.annotationTable = annotationTable;
    +    }
    +
    +    /**
    +     * Converts to a String representation.
    +     *
    +     * @return String representation
    +     */
    +    @Override
    +    public final String toString() {
    +        final StringBuilder buf = new StringBuilder(Const.getAttributeName(getTag()));
    +        buf.append(":\n");
    +        for (int i = 0; i < annotationTable.length; i++) {
    +            buf.append("  ").append(annotationTable[i]);
    +            if (i < annotationTable.length - 1) {
    +                buf.append('\n');
    +            }
    +        }
    +        return buf.toString();
    +    }
    +
         protected void writeAnnotations(final DataOutputStream dos) throws IOException {
             if (annotationTable == null) {
                 return;
    @@ -114,4 +159,5 @@
                 element.dump(dos);
             }
         }
    +
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ArrayElementValue.java	2023-10-06 05:33:33.000000000 +0000
    @@ -27,40 +27,20 @@
     /**
      * @since 6.0
      */
    -public class ArrayElementValue extends ElementValue
    -{
    +public class ArrayElementValue extends ElementValue {
         // For array types, this is the array
         private final ElementValue[] elementValues;
     
    -    @Override
    -    public String toString()
    -    {
    -        final StringBuilder sb = new StringBuilder();
    -        sb.append("{");
    -        for (int i = 0; i < elementValues.length; i++)
    -        {
    -            sb.append(elementValues[i]);
    -            if ((i + 1) < elementValues.length) {
    -                sb.append(",");
    -            }
    -        }
    -        sb.append("}");
    -        return sb.toString();
    -    }
    -
    -    public ArrayElementValue(final int type, final ElementValue[] datums, final ConstantPool cpool)
    -    {
    +    public ArrayElementValue(final int type, final ElementValue[] datums, final ConstantPool cpool) {
             super(type, cpool);
             if (type != ARRAY) {
    -            throw new IllegalArgumentException(
    -                    "Only element values of type array can be built with this ctor - type specified: " + type);
    +            throw new ClassFormatException("Only element values of type array can be built with this ctor - type specified: " + type);
             }
             this.elementValues = datums;
         }
     
         @Override
    -    public void dump(final DataOutputStream dos) throws IOException
    -    {
    +    public void dump(final DataOutputStream dos) throws IOException {
             dos.writeByte(super.getType()); // u1 type of value (ARRAY == '[')
             dos.writeShort(elementValues.length);
             for (final ElementValue evalue : elementValues) {
    @@ -68,15 +48,21 @@
             }
         }
     
    +    public ElementValue[] getElementValuesArray() {
    +        return elementValues;
    +    }
    +
    +    public int getElementValuesArraySize() {
    +        return elementValues.length;
    +    }
    +
         @Override
    -    public String stringifyValue()
    -    {
    +    public String stringifyValue() {
             final StringBuilder sb = new StringBuilder();
             sb.append("[");
    -        for (int i = 0; i < elementValues.length; i++)
    -        {
    +        for (int i = 0; i < elementValues.length; i++) {
                 sb.append(elementValues[i].stringifyValue());
    -            if ((i + 1) < elementValues.length) {
    +            if (i + 1 < elementValues.length) {
                     sb.append(",");
                 }
             }
    @@ -84,13 +70,17 @@
             return sb.toString();
         }
     
    -    public ElementValue[] getElementValuesArray()
    -    {
    -        return elementValues;
    -    }
    -
    -    public int getElementValuesArraySize()
    -    {
    -        return elementValues.length;
    +    @Override
    +    public String toString() {
    +        final StringBuilder sb = new StringBuilder();
    +        sb.append("{");
    +        for (int i = 0; i < elementValues.length; i++) {
    +            sb.append(elementValues[i]);
    +            if (i + 1 < elementValues.length) {
    +                sb.append(",");
    +            }
    +        }
    +        sb.append("}");
    +        return sb.toString();
         }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java	2023-10-06 05:33:33.000000000 +0000
    @@ -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.
      */
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
    @@ -27,14 +27,20 @@
     import java.util.Map;
     
     import com.sun.org.apache.bcel.internal.Const;
    +import com.sun.org.apache.bcel.internal.util.Args;
     
     /**
    - * Abstract super class for Attribute objects. Currently the
    - * ConstantValue, SourceFile, Code,
    - * Exceptiontable, LineNumberTable,
    - * LocalVariableTable, InnerClasses and
    - * Synthetic attributes are supported. The Unknown
    - * attribute stands for non-standard-attributes.
    + * Abstract super class for Attribute objects. Currently the ConstantValue, SourceFile, Code, Exceptiontable,
    + * LineNumberTable, LocalVariableTable, InnerClasses and Synthetic attributes are supported. The Unknown attribute
    + * stands for non-standard-attributes.
    + *
    + * 
    + * attribute_info {
    + *   u2 attribute_name_index;
    + *   u4 attribute_length;
    + *   u1 info[attribute_length];
    + * }
    + * 
    * * @see ConstantValue * @see SourceFile @@ -47,28 +53,29 @@ * @see Synthetic * @see Deprecated * @see Signature - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public abstract class Attribute implements Cloneable, Node { private static final boolean debug = false; - private int name_index; // Points to attribute name in constant pool - private int length; // Content length of attribute field - private final byte tag; // Tag to distinguish subclasses - private ConstantPool constant_pool; - private static final Map readers = new HashMap<>(); + private static final Map READERS = new HashMap<>(); + + /** + * Empty array. + * + * @since 6.6.0 + */ + public static final Attribute[] EMPTY_ARRAY = {}; /** - * Add an Attribute reader capable of parsing (user-defined) attributes - * named "name". You should not add readers for the standard attributes such - * as "LineNumberTable", because those are handled internally. + * Add an Attribute reader capable of parsing (user-defined) attributes named "name". You should not add readers for the + * standard attributes such as "LineNumberTable", because those are handled internally. * * @param name the name of the attribute as stored in the class file - * @param r the reader object + * @param unknownAttributeReader the reader object */ - public static void addAttributeReader(final String name, final UnknownAttributeReader r) - { - readers.put(name, r); + public static void addAttributeReader(final String name, final UnknownAttributeReader unknownAttributeReader) { + READERS.put(name, unknownAttributeReader); } protected static void println(final String msg) { @@ -78,135 +85,122 @@ } /** - * Class method reads one attribute from the input data stream. This method - * must not be accessible from the outside. It is called by the Field and - * Method constructor methods. + * Class method reads one attribute from the input data stream. This method must not be accessible from the outside. It + * is called by the Field and Method constructor methods. * * @see Field * @see Method * - * @param file Input stream - * @param constant_pool Array of constants + * @param dataInput Input stream + * @param constantPool Array of constants * @return Attribute - * @throws IOException - * @throws ClassFormatException + * @throws IOException if an I/O error occurs. * @since 6.0 */ - public static Attribute readAttribute(final DataInput file, final ConstantPool constant_pool) - throws IOException, ClassFormatException - { + public static Attribute readAttribute(final DataInput dataInput, final ConstantPool constantPool) throws IOException { byte tag = Const.ATTR_UNKNOWN; // Unknown attribute - // Get class name from constant pool via `name_index' indirection - final int name_index = file.readUnsignedShort(); - final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); - final String name = c.getBytes(); + // Get class name from constant pool via 'name_index' indirection + final int nameIndex = dataInput.readUnsignedShort(); + final String name = constantPool.getConstantUtf8(nameIndex).getBytes(); // Length of data in bytes - final int length = file.readInt(); + final int length = dataInput.readInt(); // Compare strings to find known attribute - for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++) - { - if (name.equals(Const.getAttributeName(i))) - { + for (byte i = 0; i < Const.KNOWN_ATTRIBUTES; i++) { + if (name.equals(Const.getAttributeName(i))) { tag = i; // found! break; } } - // Call proper constructor, depending on `tag' - switch (tag) - { - case Const.ATTR_UNKNOWN: - final Object r = readers.get(name); - if (r instanceof UnknownAttributeReader) - { - return ((UnknownAttributeReader) r).createAttribute(name_index, length, file, constant_pool); - } - return new Unknown(name_index, length, file, constant_pool); - case Const.ATTR_CONSTANT_VALUE: - return new ConstantValue(name_index, length, file, constant_pool); - case Const.ATTR_SOURCE_FILE: - return new SourceFile(name_index, length, file, constant_pool); - case Const.ATTR_CODE: - return new Code(name_index, length, file, constant_pool); - case Const.ATTR_EXCEPTIONS: - return new ExceptionTable(name_index, length, file, constant_pool); - case Const.ATTR_LINE_NUMBER_TABLE: - return new LineNumberTable(name_index, length, file, constant_pool); - case Const.ATTR_LOCAL_VARIABLE_TABLE: - return new LocalVariableTable(name_index, length, file, constant_pool); - case Const.ATTR_INNER_CLASSES: - return new InnerClasses(name_index, length, file, constant_pool); - case Const.ATTR_SYNTHETIC: - return new Synthetic(name_index, length, file, constant_pool); - case Const.ATTR_DEPRECATED: - return new Deprecated(name_index, length, file, constant_pool); - case Const.ATTR_PMG: - return new PMGClass(name_index, length, file, constant_pool); - case Const.ATTR_SIGNATURE: - return new Signature(name_index, length, file, constant_pool); - case Const.ATTR_STACK_MAP: - // old style stack map: unneeded for JDK5 and below; - // illegal(?) for JDK6 and above. So just delete with a warning. - println("Warning: Obsolete StackMap attribute ignored."); - return new Unknown(name_index, length, file, constant_pool); - case Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: - return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool); - case Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: - return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool); - case Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: - return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool); - case Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: - return new RuntimeInvisibleParameterAnnotations(name_index, length, file, constant_pool); - case Const.ATTR_ANNOTATION_DEFAULT: - return new AnnotationDefault(name_index, length, file, constant_pool); - case Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE: - return new LocalVariableTypeTable(name_index, length, file, constant_pool); - case Const.ATTR_ENCLOSING_METHOD: - return new EnclosingMethod(name_index, length, file, constant_pool); - case Const.ATTR_STACK_MAP_TABLE: - // read new style stack map: StackMapTable. The rest of the code - // calls this a StackMap for historical reasons. - return new StackMap(name_index, length, file, constant_pool); - case Const.ATTR_BOOTSTRAP_METHODS: - return new BootstrapMethods(name_index, length, file, constant_pool); - case Const.ATTR_METHOD_PARAMETERS: - return new MethodParameters(name_index, length, file, constant_pool); - case Const.ATTR_MODULE: - return new Module(name_index, length, file, constant_pool); - case Const.ATTR_MODULE_PACKAGES: - return new ModulePackages(name_index, length, file, constant_pool); - case Const.ATTR_MODULE_MAIN_CLASS: - return new ModuleMainClass(name_index, length, file, constant_pool); - case Const.ATTR_NEST_HOST: - return new NestHost(name_index, length, file, constant_pool); - case Const.ATTR_NEST_MEMBERS: - return new NestMembers(name_index, length, file, constant_pool); - default: - // Never reached - throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag); + // Call proper constructor, depending on 'tag' + switch (tag) { + case Const.ATTR_UNKNOWN: + final Object r = READERS.get(name); + if (r instanceof UnknownAttributeReader) { + return ((UnknownAttributeReader) r).createAttribute(nameIndex, length, dataInput, constantPool); + } + return new Unknown(nameIndex, length, dataInput, constantPool); + case Const.ATTR_CONSTANT_VALUE: + return new ConstantValue(nameIndex, length, dataInput, constantPool); + case Const.ATTR_SOURCE_FILE: + return new SourceFile(nameIndex, length, dataInput, constantPool); + case Const.ATTR_CODE: + return new Code(nameIndex, length, dataInput, constantPool); + case Const.ATTR_EXCEPTIONS: + return new ExceptionTable(nameIndex, length, dataInput, constantPool); + case Const.ATTR_LINE_NUMBER_TABLE: + return new LineNumberTable(nameIndex, length, dataInput, constantPool); + case Const.ATTR_LOCAL_VARIABLE_TABLE: + return new LocalVariableTable(nameIndex, length, dataInput, constantPool); + case Const.ATTR_INNER_CLASSES: + return new InnerClasses(nameIndex, length, dataInput, constantPool); + case Const.ATTR_SYNTHETIC: + return new Synthetic(nameIndex, length, dataInput, constantPool); + case Const.ATTR_DEPRECATED: + return new Deprecated(nameIndex, length, dataInput, constantPool); + case Const.ATTR_PMG: + return new PMGClass(nameIndex, length, dataInput, constantPool); + case Const.ATTR_SIGNATURE: + return new Signature(nameIndex, length, dataInput, constantPool); + case Const.ATTR_STACK_MAP: + // old style stack map: unneeded for JDK5 and below; + // illegal(?) for JDK6 and above. So just delete with a warning. + println("Warning: Obsolete StackMap attribute ignored."); + return new Unknown(nameIndex, length, dataInput, constantPool); + case Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS: + return new RuntimeVisibleAnnotations(nameIndex, length, dataInput, constantPool); + case Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS: + return new RuntimeInvisibleAnnotations(nameIndex, length, dataInput, constantPool); + case Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeVisibleParameterAnnotations(nameIndex, length, dataInput, constantPool); + case Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS: + return new RuntimeInvisibleParameterAnnotations(nameIndex, length, dataInput, constantPool); + case Const.ATTR_ANNOTATION_DEFAULT: + return new AnnotationDefault(nameIndex, length, dataInput, constantPool); + case Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE: + return new LocalVariableTypeTable(nameIndex, length, dataInput, constantPool); + case Const.ATTR_ENCLOSING_METHOD: + return new EnclosingMethod(nameIndex, length, dataInput, constantPool); + case Const.ATTR_STACK_MAP_TABLE: + // read new style stack map: StackMapTable. The rest of the code + // calls this a StackMap for historical reasons. + return new StackMap(nameIndex, length, dataInput, constantPool); + case Const.ATTR_BOOTSTRAP_METHODS: + return new BootstrapMethods(nameIndex, length, dataInput, constantPool); + case Const.ATTR_METHOD_PARAMETERS: + return new MethodParameters(nameIndex, length, dataInput, constantPool); + case Const.ATTR_MODULE: + return new Module(nameIndex, length, dataInput, constantPool); + case Const.ATTR_MODULE_PACKAGES: + return new ModulePackages(nameIndex, length, dataInput, constantPool); + case Const.ATTR_MODULE_MAIN_CLASS: + return new ModuleMainClass(nameIndex, length, dataInput, constantPool); + case Const.ATTR_NEST_HOST: + return new NestHost(nameIndex, length, dataInput, constantPool); + case Const.ATTR_NEST_MEMBERS: + return new NestMembers(nameIndex, length, dataInput, constantPool); + default: + // Never reached + throw new IllegalStateException("Unrecognized attribute type tag parsed: " + tag); } } /** - * Class method reads one attribute from the input data stream. This method - * must not be accessible from the outside. It is called by the Field and - * Method constructor methods. + * Class method reads one attribute from the input data stream. This method must not be accessible from the outside. It + * is called by the Field and Method constructor methods. * * @see Field * @see Method * - * @param file Input stream - * @param constant_pool Array of constants + * @param dataInputStream Input stream + * @param constantPool Array of constants * @return Attribute - * @throws IOException - * @throws ClassFormatException + * @throws IOException if an I/O error occurs. */ - public static Attribute readAttribute(final DataInputStream file, final ConstantPool constant_pool) - throws IOException, ClassFormatException - { - return readAttribute((DataInput) file, constant_pool); + public static Attribute readAttribute(final DataInputStream dataInputStream, final ConstantPool constantPool) throws IOException { + return readAttribute((DataInput) dataInputStream, constantPool); } /** @@ -214,65 +208,95 @@ * * @param name the name of the attribute as stored in the class file */ - public static void removeAttributeReader(final String name) - { - readers.remove(name); + public static void removeAttributeReader(final String name) { + READERS.remove(name); } - protected Attribute(final byte tag, final int name_index, final int length, final ConstantPool constant_pool) - { + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected int name_index; // Points to attribute name in constant pool TODO make private (has getter & setter) + + /** + * @deprecated (since 6.0) (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected int length; // Content length of attribute field TODO make private (has getter & setter) + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected byte tag; // Tag to distinguish subclasses TODO make private & final; supposed to be immutable + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected ConstantPool constant_pool; // TODO make private (has getter & setter) + + /** + * Constructs an instance. + * + *
    +     * attribute_info {
    +     *   u2 attribute_name_index;
    +     *   u4 attribute_length;
    +     *   u1 info[attribute_length];
    +     * }
    +     * 
    + * + * @param tag tag. + * @param nameIndex u2 name index. + * @param length u4 length. + * @param constantPool constant pool. + */ + protected Attribute(final byte tag, final int nameIndex, final int length, final ConstantPool constantPool) { this.tag = tag; - this.name_index = name_index; - this.length = length; - this.constant_pool = constant_pool; + this.name_index = Args.requireU2(nameIndex, 0, constantPool.getLength(), getClass().getSimpleName() + " name index"); + this.length = Args.requireU4(length, getClass().getSimpleName() + " attribute length"); + this.constant_pool = constantPool; } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * - * @param v - * Visitor object + * @param v Visitor object */ @Override public abstract void accept(Visitor v); /** - * Use copy() if you want to have a deep copy(), i.e., with all references - * copied correctly. + * Use copy() if you want to have a deep copy(), i.e., with all references copied correctly. * * @return shallow copy of this attribute */ @Override - public Object clone() - { + public Object clone() { Attribute attr = null; - try - { + try { attr = (Attribute) super.clone(); - } - catch (final CloneNotSupportedException e) - { + } catch (final CloneNotSupportedException e) { throw new Error("Clone Not Supported"); // never happens } return attr; } /** - * @return deep copy of this attribute + * @param constantPool constant pool to save. + * @return deep copy of this attribute. */ - public abstract Attribute copy(ConstantPool _constant_pool); + public abstract Attribute copy(ConstantPool constantPool); /** - * Dump attribute to file stream in binary format. + * Dumps attribute to file stream in binary format. * - * @param file - * Output file stream - * @throws IOException + * @param file Output file stream + * @throws IOException if an I/O error occurs. */ - public void dump(final DataOutputStream file) throws IOException - { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(name_index); file.writeInt(length); } @@ -281,16 +305,14 @@ * @return Constant pool used by this object. * @see ConstantPool */ - public final ConstantPool getConstantPool() - { + public final ConstantPool getConstantPool() { return constant_pool; } /** * @return Length of attribute field in bytes. */ - public final int getLength() - { + public final int getLength() { return length; } @@ -298,59 +320,51 @@ * @return Name of attribute * @since 6.0 */ - public String getName() - { - final ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); - return c.getBytes(); + public String getName() { + return constant_pool.getConstantUtf8(name_index).getBytes(); } /** * @return Name index in constant pool of attribute name. */ - public final int getNameIndex() - { + public final int getNameIndex() { return name_index; } /** * @return Tag of attribute, i.e., its type. Value may not be altered, thus there is no setTag() method. */ - public final byte getTag() - { + public final byte getTag() { return tag; } /** - * @param constant_pool Constant pool to be used for this object. + * @param constantPool Constant pool to be used for this object. * @see ConstantPool */ - public final void setConstantPool(final ConstantPool constant_pool) - { - this.constant_pool = constant_pool; + public final void setConstantPool(final ConstantPool constantPool) { + this.constant_pool = constantPool; } /** * @param length length in bytes. */ - public final void setLength(final int length) - { + public final void setLength(final int length) { this.length = length; } /** - * @param name_index of attribute. + * @param nameIndex of attribute. */ - public final void setNameIndex(final int name_index) - { - this.name_index = name_index; + public final void setNameIndex(final int nameIndex) { + this.name_index = nameIndex; } /** * @return attribute name. */ @Override - public String toString() - { + public String toString() { return Const.getAttributeName(tag); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,10 +22,9 @@ package com.sun.org.apache.bcel.internal.classfile; /** - * Unknown (non-standard) attributes may be read via user-defined factory - * objects that can be registered with the Attribute.addAttributeReader - * method. These factory objects should implement this interface. - + * Unknown (non-standard) attributes may be read via user-defined factory objects that can be registered with the + * Attribute.addAttributeReader method. These factory objects should implement this interface. + * * @see Attribute * * @deprecated Use UnknownAttributeReader instead @@ -34,30 +33,23 @@ public interface AttributeReader { /** - When this attribute reader is added via the static method - Attribute.addAttributeReader, an attribute name is associated with it. - As the class file parser parses attributes, it will call various - AttributeReaders based on the name of the attributes it is - constructing. - - @param name_index An index into the constant pool, indexing a - ConstantUtf8 that represents the name of the attribute. - - @param length The length of the data contained in the attribute. This - is written into the constant pool and should agree with what the - factory expects the length to be. - - @param file This is the data input stream that the factory needs to read - its data from. - - @param constant_pool This is the constant pool associated with the - Attribute that we are constructing. - - @return The user-defined AttributeReader should take this data and use - it to construct an attribute. In the case of errors, a null can be - returned which will cause the parsing of the class file to fail. - - @see Attribute#addAttributeReader( String, AttributeReader ) + * When this attribute reader is added via the static method Attribute.addAttributeReader, an attribute name is + * associated with it. As the class file parser parses attributes, it will call various AttributeReaders based on the + * name of the attributes it is constructing. + * + * @param nameIndex An index into the constant pool, indexing a ConstantUtf8 that represents the name of the attribute. + * + * @param length The length of the data contained in the attribute. This is written into the constant pool and should + * agree with what the factory expects the length to be. + * + * @param file This is the data input stream that the factory needs to read its data from. + * + * @param constantPool This is the constant pool associated with the Attribute that we are constructing. + * + * @return The user-defined AttributeReader should take this data and use it to construct an attribute. In the case of + * errors, a null can be returned which will cause the parsing of the class file to fail. + * + * @see Attribute#addAttributeReader( String, AttributeReader ) */ - Attribute createAttribute( int name_index, int length, java.io.DataInputStream file, ConstantPool constant_pool ); + Attribute createAttribute(int nameIndex, int length, java.io.DataInputStream file, ConstantPool constantPool); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethod.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,12 +29,11 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents a bootstrap method attribute, i.e., the bootstrap - * method ref, the number of bootstrap arguments and an array of the - * bootstrap arguments. + * This class represents a bootstrap method attribute, i.e., the bootstrap method ref, the number of bootstrap arguments + * and an array of the bootstrap arguments. * - * @see - * The class File Format : The BootstrapMethods Attribute + * @see The class File Format : + * The BootstrapMethods Attribute * @since 6.0 */ public class BootstrapMethod implements Cloneable { @@ -45,9 +44,10 @@ /** Array of references to the constant_pool table */ private int[] bootstrapArguments; - /** * Initialize from another object. + * + * @param c Source to copy. */ public BootstrapMethod(final BootstrapMethod c) { this(c.getBootstrapMethodRef(), c.getBootstrapArguments()); @@ -57,7 +57,7 @@ * Construct object from input stream. * * @param input Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ BootstrapMethod(final DataInput input) throws IOException { this(input.readUnsignedShort(), input.readUnsignedShort()); @@ -68,8 +68,8 @@ } // helper method - private BootstrapMethod(final int bootstrap_method_ref, final int num_bootstrap_arguments) { - this(bootstrap_method_ref, new int[num_bootstrap_arguments]); + private BootstrapMethod(final int bootstrapMethodRef, final int numBootstrapArguments) { + this(bootstrapMethodRef, new int[numBootstrapArguments]); } /** @@ -82,17 +82,29 @@ } /** - * @return index into constant_pool of bootstrap_method + * @return deep copy of this object */ - public int getBootstrapMethodRef() { - return bootstrapMethodRef; + public BootstrapMethod copy() { + try { + return (BootstrapMethod) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; } /** - * @param bootstrapMethodRef int index into constant_pool of CONSTANT_MethodHandle + * Dump object to file stream in binary format. + * + * @param file Output file stream + * @throws IOException if an I/O error occurs. */ - public void setBootstrapMethodRef(final int bootstrapMethodRef) { - this.bootstrapMethodRef = bootstrapMethodRef; + public final void dump(final DataOutputStream file) throws IOException { + file.writeShort(bootstrapMethodRef); + file.writeShort(bootstrapArguments.length); + for (final int bootstrapArgument : bootstrapArguments) { + file.writeShort(bootstrapArgument); + } } /** @@ -103,6 +115,13 @@ } /** + * @return index into constant_pool of bootstrap_method + */ + public int getBootstrapMethodRef() { + return bootstrapMethodRef; + } + + /** * @return count of number of boostrap arguments */ public int getNumBootstrapArguments() { @@ -117,57 +136,35 @@ } /** + * @param bootstrapMethodRef int index into constant_pool of CONSTANT_MethodHandle + */ + public void setBootstrapMethodRef(final int bootstrapMethodRef) { + this.bootstrapMethodRef = bootstrapMethodRef; + } + + /** * @return String representation. */ @Override public final String toString() { - return "BootstrapMethod(" + bootstrapMethodRef + ", " + bootstrapArguments.length + ", " - + Arrays.toString(bootstrapArguments) + ")"; + return "BootstrapMethod(" + bootstrapMethodRef + ", " + bootstrapArguments.length + ", " + Arrays.toString(bootstrapArguments) + ")"; } /** * @return Resolved string representation */ - public final String toString( final ConstantPool constantPool ) { + public final String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - String bootstrap_method_name; - bootstrap_method_name = constantPool.constantToString(bootstrapMethodRef, - Const.CONSTANT_MethodHandle); - buf.append(Utility.compactClassName(bootstrap_method_name, false)); - final int num_bootstrap_arguments = bootstrapArguments.length; - if (num_bootstrap_arguments > 0) { + final String bootstrapMethodName = constantPool.constantToString(bootstrapMethodRef, Const.CONSTANT_MethodHandle); + buf.append(Utility.compactClassName(bootstrapMethodName, false)); + final int bootstrapArgumentsLen = bootstrapArguments.length; + if (bootstrapArgumentsLen > 0) { buf.append("\nMethod Arguments:"); - for (int i = 0; i < num_bootstrap_arguments; i++) { + for (int i = 0; i < bootstrapArgumentsLen; i++) { buf.append("\n ").append(i).append(": "); buf.append(constantPool.constantToString(constantPool.getConstant(bootstrapArguments[i]))); } } return buf.toString(); } - - /** - * Dump object to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(final DataOutputStream file) throws IOException { - file.writeShort(bootstrapMethodRef); - file.writeShort(bootstrapArguments.length); - for (final int bootstrap_argument : bootstrapArguments) { - file.writeShort(bootstrap_argument); - } - } - - /** - * @return deep copy of this object - */ - public BootstrapMethod copy() { - try { - return (BootstrapMethod) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/BootstrapMethods.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,74 +24,63 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Iterator; +import java.util.stream.Stream; import com.sun.org.apache.bcel.internal.Const; /** * This class represents a BootstrapMethods attribute. * - * @see - * The class File Format : The BootstrapMethods Attribute + * @see The class File Format : + * The BootstrapMethods Attribute * @since 6.0 */ -public class BootstrapMethods extends Attribute { +public class BootstrapMethods extends Attribute implements Iterable { - private BootstrapMethod[] bootstrapMethods; // TODO this could be made final (setter is not used) + private BootstrapMethod[] bootstrapMethods; // TODO this could be made final (setter is not used) /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. */ public BootstrapMethods(final BootstrapMethods c) { this(c.getNameIndex(), c.getLength(), c.getBootstrapMethods(), c.getConstantPool()); } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param bootstrapMethods array of bootstrap methods - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public BootstrapMethods(final int name_index, final int length, final BootstrapMethod[] bootstrapMethods, final ConstantPool constant_pool) { - super(Const.ATTR_BOOTSTRAP_METHODS, name_index, length, constant_pool); + public BootstrapMethods(final int nameIndex, final int length, final BootstrapMethod[] bootstrapMethods, final ConstantPool constantPool) { + super(Const.ATTR_BOOTSTRAP_METHODS, nameIndex, length, constantPool); this.bootstrapMethods = bootstrapMethods; } /** * Construct object from Input stream. * - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - BootstrapMethods(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, (BootstrapMethod[]) null, constant_pool); + BootstrapMethods(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (BootstrapMethod[]) null, constantPool); - final int num_bootstrap_methods = input.readUnsignedShort(); - bootstrapMethods = new BootstrapMethod[num_bootstrap_methods]; - for (int i = 0; i < num_bootstrap_methods; i++) { + final int numBootstrapMethods = input.readUnsignedShort(); + bootstrapMethods = new BootstrapMethod[numBootstrapMethods]; + for (int i = 0; i < numBootstrapMethods; i++) { bootstrapMethods[i] = new BootstrapMethod(input); } } /** - * @return array of bootstrap method "records" - */ - public final BootstrapMethod[] getBootstrapMethods() { - return bootstrapMethods; - } - - /** - * @param bootstrapMethods the array of bootstrap methods - */ - public final void setBootstrapMethods(final BootstrapMethod[] bootstrapMethods) { - this.bootstrapMethods = bootstrapMethods; - } - - /** * @param v Visitor object */ @Override @@ -103,14 +92,14 @@ * @return deep copy of this attribute */ @Override - public BootstrapMethods copy(final ConstantPool _constant_pool) { + public BootstrapMethods copy(final ConstantPool constantPool) { final BootstrapMethods c = (BootstrapMethods) clone(); c.bootstrapMethods = new BootstrapMethod[bootstrapMethods.length]; for (int i = 0; i < bootstrapMethods.length; i++) { c.bootstrapMethods[i] = bootstrapMethods[i].copy(); } - c.setConstantPool(_constant_pool); + c.setConstantPool(constantPool); return c; } @@ -118,19 +107,38 @@ * Dump bootstrap methods attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override public final void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(bootstrapMethods.length); - for (final BootstrapMethod bootstrap_method : bootstrapMethods) { - bootstrap_method.dump(file); + for (final BootstrapMethod bootstrapMethod : bootstrapMethods) { + bootstrapMethod.dump(file); } } /** + * @return array of bootstrap method "records" + */ + public final BootstrapMethod[] getBootstrapMethods() { + return bootstrapMethods; + } + + @Override + public Iterator iterator() { + return Stream.of(bootstrapMethods).iterator(); + } + + /** + * @param bootstrapMethods the array of bootstrap methods + */ + public final void setBootstrapMethods(final BootstrapMethod[] bootstrapMethods) { + this.bootstrapMethods = bootstrapMethods; + } + + /** * @return String representation. */ @Override @@ -143,11 +151,11 @@ buf.append("\n"); final int start = buf.length(); buf.append(" ").append(i).append(": "); - final int indent_count = buf.length() - start; - final String[] lines = (bootstrapMethods[i].toString(super.getConstantPool())).split("\\r?\\n"); + final int indentCount = buf.length() - start; + final String[] lines = bootstrapMethods[i].toString(super.getConstantPool()).split("\\r?\\n"); buf.append(lines[0]); for (int j = 1; j < lines.length; j++) { - buf.append("\n").append(" ".substring(0,indent_count)).append(lines[j]); + buf.append("\n").append(" ", 0, indentCount).append(lines[j]); } } return buf.toString(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassElementValue.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,48 +24,36 @@ import java.io.DataOutputStream; import java.io.IOException; -import com.sun.org.apache.bcel.internal.Const; - /** * @since 6.0 */ -public class ClassElementValue extends ElementValue -{ +public class ClassElementValue extends ElementValue { // For primitive types and string type, this points to the value entry in // the cpool // For 'class' this points to the class entry in the cpool private final int idx; - public ClassElementValue(final int type, final int idx, final ConstantPool cpool) - { + public ClassElementValue(final int type, final int idx, final ConstantPool cpool) { super(type, cpool); this.idx = idx; } - public int getIndex() - { - return idx; + @Override + public void dump(final DataOutputStream dos) throws IOException { + dos.writeByte(super.getType()); // u1 kind of value + dos.writeShort(idx); } - public String getClassString() - { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(idx, - Const.CONSTANT_Utf8); - return c.getBytes(); + public String getClassString() { + return super.getConstantPool().getConstantUtf8(idx).getBytes(); } - @Override - public String stringifyValue() - { - final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(idx, - Const.CONSTANT_Utf8); - return cu8.getBytes(); + public int getIndex() { + return idx; } @Override - public void dump(final DataOutputStream dos) throws IOException - { - dos.writeByte(super.getType()); // u1 kind of value - dos.writeShort(idx); + public String stringifyValue() { + return super.getConstantPool().getConstantUtf8(idx).getBytes(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,28 +22,52 @@ package com.sun.org.apache.bcel.internal.classfile; /** - * Thrown when the BCEL attempts to read a class file and determines - * that the file is malformed or otherwise cannot be interpreted as a - * class file. - * + * Thrown when the BCEL attempts to read a class file and determines that a class is malformed or otherwise cannot be interpreted as a class file. */ public class ClassFormatException extends RuntimeException { private static final long serialVersionUID = -3569097343160139969L; + /** + * Constructs a new instance with {@code null} as its detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link #initCause}. + */ public ClassFormatException() { - super(); } - - public ClassFormatException(final String s) { - super(s); + /** + * Constructs a new instance with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to + * {@link #initCause}. + * + * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()} method. + */ + public ClassFormatException(final String message) { + super(message); } /** + * Constructs a new instance with the specified detail message and cause. + *

    + * Note that the detail message associated with {@code cause} is not automatically incorporated in this runtime exception's detail message. + * + * @param message the detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that + * the cause is nonexistent or unknown.) * @since 6.0 */ public ClassFormatException(final String message, final Throwable cause) { super(message, cause); } + + /** + * Constructs a new instance with the specified cause and a detail message of {@code (cause==null ? null : cause.toString())} (which typically contains the + * class and detail message of {@code cause}). This constructor is useful for runtime exceptions that are little more than wrappers for other throwables. + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the + * cause is nonexistent or unknown.) + * @since 6.7.0 + */ + public ClassFormatException(final Throwable cause) { + super(cause); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java 2023-10-06 05:33:33.000000000 +0000 @@ -32,20 +32,17 @@ import com.sun.org.apache.bcel.internal.Const; /** - * Wrapper class that parses a given Java .class file. The method parse returns a - * JavaClass object on success. When an I/O error or an - * inconsistency occurs an appropiate exception is propagated back to - * the caller. - * - * The structure and the names comply, except for a few conveniences, - * exactly with the - * JVM specification 1.0. See this paper for - * further details about the structure of a bytecode file. + * Wrapper class that parses a given Java .class file. The method parse returns a + * JavaClass object on success. When an I/O error or an inconsistency occurs an + * appropriate exception is propagated back to the caller. * + * The structure and the names comply, except for a few conveniences, exactly with the + * JVM specification 1.0. See this paper for further details about + * the structure of a bytecode file. */ public final class ClassParser { + private static final int BUFSIZE = 8192; private DataInputStream dataInputStream; private final boolean fileOwned; private final String fileName; @@ -61,8 +58,6 @@ private Method[] methods; // methods defined in the class private Attribute[] attributes; // attributes defined in the class private final boolean isZip; // Loaded from zip file - private static final int BUFSIZE = 8192; - /** * Parses class from the given stream. @@ -72,9 +67,9 @@ */ public ClassParser(final InputStream inputStream, final String fileName) { this.fileName = fileName; - fileOwned = false; + this.fileOwned = false; final String clazz = inputStream.getClass().getName(); // Not a very clean solution ... - isZip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); + this.isZip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); if (inputStream instanceof DataInputStream) { this.dataInputStream = (DataInputStream) inputStream; } else { @@ -82,41 +77,38 @@ } } - - /** Parses class from given .class file. + /** + * Parses class from given .class file. * * @param fileName file name */ public ClassParser(final String fileName) { - isZip = false; + this.isZip = false; this.fileName = fileName; - fileOwned = true; + this.fileOwned = true; } - - /** Parses class from given .class file in a ZIP-archive + /** + * Parses class from given .class file in a ZIP-archive * * @param zipFile zip file name * @param fileName file name */ public ClassParser(final String zipFile, final String fileName) { - isZip = true; - fileOwned = true; + this.isZip = true; + this.fileOwned = true; this.zipFile = zipFile; this.fileName = fileName; } - /** - * Parses the given Java class file and return an object that represents - * the contained data, i.e., constants, methods, fields and commands. - * A ClassFormatException is raised, if the file is not a valid - * .class file. (This does not include verification of the byte code as it - * is performed by the java interpreter). + * Parses the given Java class file and return an object that represents the contained data, i.e., constants, methods, + * fields and commands. A ClassFormatException is raised, if the file is not a valid .class file. (This does + * not include verification of the byte code as it is performed by the java interpreter). * * @return Class object representing the parsed class file - * @throws IOException - * @throws ClassFormatException + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ public JavaClass parse() throws IOException, ClassFormatException { ZipFile zip = null; @@ -130,11 +122,9 @@ throw new IOException("File " + fileName + " not found"); } - dataInputStream = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), - BUFSIZE)); + dataInputStream = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), BUFSIZE)); } else { - dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream( - fileName), BUFSIZE)); + dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(fileName), BUFSIZE)); } } /****************** Read headers ********************************/ @@ -157,19 +147,19 @@ // Read class attributes readAttributes(); // Check for unknown variables - //Unknown[] u = Unknown.getUnknownAttributes(); - //for (int i=0; i < u.length; i++) - // System.err.println("WARNING: " + u[i]); + // Unknown[] u = Unknown.getUnknownAttributes(); + // for (int i=0; i < u.length; i++) + // System.err.println("WARNING: " + u[i]); // Everything should have been read now - // if(file.available() > 0) { - // int bytes = file.available(); - // byte[] buf = new byte[bytes]; - // file.read(buf); - // if(!(isZip && (buf.length == 1))) { - // System.err.println("WARNING: Trailing garbage at end of " + fileName); - // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); - // } - // } + // if(file.available() > 0) { + // int bytes = file.available(); + // byte[] buf = new byte[bytes]; + // file.read(buf); + // if(!(isZip && (buf.length == 1))) { + // System.err.println("WARNING: Trailing garbage at end of " + fileName); + // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); + // } + // } } finally { // Read everything of interest, so close the file if (fileOwned) { @@ -177,92 +167,88 @@ if (dataInputStream != null) { dataInputStream.close(); } - } catch (final IOException ioe) { - //ignore close exceptions + } catch (final IOException ignored) { + // ignore close exceptions } } try { if (zip != null) { zip.close(); } - } catch (final IOException ioe) { - //ignore close exceptions + } catch (final IOException ignored) { + // ignore close exceptions } } // Return the information we have gathered in a new object - return new JavaClass(classNameIndex, superclassNameIndex, fileName, major, minor, - accessFlags, constantPool, interfaces, fields, methods, attributes, isZip - ? JavaClass.ZIP - : JavaClass.FILE); + return new JavaClass(classNameIndex, superclassNameIndex, fileName, major, minor, accessFlags, constantPool, interfaces, fields, methods, attributes, + isZip ? JavaClass.ZIP : JavaClass.FILE); } - /** * Reads information about the attributes of the class. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readAttributes() throws IOException, ClassFormatException { - final int attributes_count = dataInputStream.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { + final int attributesCount = dataInputStream.readUnsignedShort(); + attributes = new Attribute[attributesCount]; + for (int i = 0; i < attributesCount; i++) { attributes[i] = Attribute.readAttribute(dataInputStream, constantPool); } } - /** * Reads information about the class and its super class. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readClassInfo() throws IOException, ClassFormatException { accessFlags = dataInputStream.readUnsignedShort(); - /* Interfaces are implicitely abstract, the flag should be set - * according to the JVM specification. + /* + * Interfaces are implicitly abstract, the flag should be set according to the JVM specification. */ if ((accessFlags & Const.ACC_INTERFACE) != 0) { accessFlags |= Const.ACC_ABSTRACT; } - if (((accessFlags & Const.ACC_ABSTRACT) != 0) - && ((accessFlags & Const.ACC_FINAL) != 0)) { + if ((accessFlags & Const.ACC_ABSTRACT) != 0 && (accessFlags & Const.ACC_FINAL) != 0) { throw new ClassFormatException("Class " + fileName + " can't be both final and abstract"); } classNameIndex = dataInputStream.readUnsignedShort(); superclassNameIndex = dataInputStream.readUnsignedShort(); } - /** * Reads constant pool entries. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readConstantPool() throws IOException, ClassFormatException { constantPool = new ConstantPool(dataInputStream); } - /** * Reads information about the fields of the class, i.e., its variables. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readFields() throws IOException, ClassFormatException { - final int fields_count = dataInputStream.readUnsignedShort(); - fields = new Field[fields_count]; - for (int i = 0; i < fields_count; i++) { + final int fieldsCount = dataInputStream.readUnsignedShort(); + fields = new Field[fieldsCount]; + for (int i = 0; i < fieldsCount; i++) { fields[i] = new Field(dataInputStream, constantPool); } } - /******************** Private utility methods **********************/ /** - * Checks whether the header of the file is ok. - * Of course, this has to be the first action on successive file reads. - * @throws IOException - * @throws ClassFormatException + * Checks whether the header of the file is ok. Of course, this has to be the first action on successive file reads. + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readID() throws IOException, ClassFormatException { if (dataInputStream.readInt() != Const.JVM_CLASSFILE_MAGIC) { @@ -270,39 +256,39 @@ } } - /** * Reads information about the interfaces implemented by this class. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readInterfaces() throws IOException, ClassFormatException { - final int interfaces_count = dataInputStream.readUnsignedShort(); - interfaces = new int[interfaces_count]; - for (int i = 0; i < interfaces_count; i++) { + final int interfacesCount = dataInputStream.readUnsignedShort(); + interfaces = new int[interfacesCount]; + for (int i = 0; i < interfacesCount; i++) { interfaces[i] = dataInputStream.readUnsignedShort(); } } - /** * Reads information about the methods of the class. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ - private void readMethods() throws IOException, ClassFormatException { - final int methods_count = dataInputStream.readUnsignedShort(); - methods = new Method[methods_count]; - for (int i = 0; i < methods_count; i++) { + private void readMethods() throws IOException { + final int methodsCount = dataInputStream.readUnsignedShort(); + methods = new Method[methodsCount]; + for (int i = 0; i < methodsCount; i++) { methods[i] = new Method(dataInputStream, constantPool); } } - /** * Reads major and minor version of compiler which created the file. - * @throws IOException - * @throws ClassFormatException + * + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ private void readVersion() throws IOException, ClassFormatException { minor = dataInputStream.readUnsignedShort(); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -25,101 +25,136 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class represents an entry in the exception table of the Code - * attribute and is used only there. It contains a range in which a - * particular exception handler is active. + * This class represents an entry in the exception table of the Code attribute and is used only there. It + * contains a range in which a particular exception handler is active. * - * @see Code - * @LastModified: May 2021 + *

    + * Code_attribute {
    + *   u2 attribute_name_index;
    + *   u4 attribute_length;
    + *   u2 max_stack;
    + *   u2 max_locals;
    + *   u4 code_length;
    + *   u1 code[code_length];
    + *   u2 exception_table_length;
    + *   {
    + *     u2 start_pc;
    + *     u2 end_pc;
    + *     u2 handler_pc;
    + *     u2 catch_type;
    + *   } exception_table[exception_table_length];
    + *   u2 attributes_count;
    + *   attribute_info attributes[attributes_count];
    + * }
    + * 
    + * + * @see Code + * @LastModified: Feb 2023 */ public final class CodeException implements Cloneable, Node { - private int startPc; // Range in the code the exception handler is - private int endPc; // active. startPc is inclusive, endPc exclusive - private int handlerPc; /* Starting address of exception handler, i.e., - * an offset from start of code. + /** + * Empty array. */ - private int catchType; /* If this is zero the handler catches any - * exception, otherwise it points to the - * exception class which is to be caught. + static final CodeException[] EMPTY_CODE_EXCEPTION_ARRAY = {}; + + /** Range in the code the exception handler. */ + private int startPc; + + /** active. startPc is inclusive, endPc exclusive. */ + private int endPc; + + /** + * Starting address of exception handler, i.e., an offset from start of code. */ + private int handlerPc; + /* + * If this is zero the handler catches any exception, otherwise it points to the exception class which is to be caught. + */ + private int catchType; /** - * Initialize from another object. + * Constructs a new instance from another instance. + * + * @param c Source for copying. */ public CodeException(final CodeException c) { this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); } - /** - * Construct object from file stream. + * Constructs a new instance from a DataInput. + * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ CodeException(final DataInput file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort()); + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort()); } - /** - * @param startPc Range in the code the exception handler is active, - * startPc is inclusive while + * Constructs a new instance. + * + * @param startPc Range in the code the exception handler is active, startPc is inclusive while * @param endPc is exclusive - * @param handlerPc Starting address of exception handler, i.e., - * an offset from start of code. - * @param catchType If zero the handler catches any - * exception, otherwise it points to the exception class which is - * to be caught. + * @param handlerPc Starting address of exception handler, i.e., an offset from start of code. + * @param catchType If zero the handler catches any exception, otherwise it points to the exception class which is to be + * caught. */ public CodeException(final int startPc, final int endPc, final int handlerPc, final int catchType) { - this.startPc = startPc; - this.endPc = endPc; - this.handlerPc = handlerPc; - this.catchType = catchType; + this.startPc = Args.requireU2(startPc, "startPc"); + this.endPc = Args.requireU2(endPc, "endPc"); + this.handlerPc = Args.requireU2(handlerPc, "handlerPc"); + this.catchType = Args.requireU2(catchType, "catchType"); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitCodeException(this); } + /** + * @return deep copy of this object + */ + public CodeException copy() { + try { + return (CodeException) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } /** - * Dump code exception to file stream in binary format. + * Dumps code exception to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(startPc); file.writeShort(endPc); file.writeShort(handlerPc); file.writeShort(catchType); } - /** - * @return 0, if the handler catches any exception, otherwise it points to - * the exception class which is to be caught. + * @return 0, if the handler catches any exception, otherwise it points to the exception class which is to be caught. */ public int getCatchType() { return catchType; } - /** * @return Exclusive end index of the region where the handler is active. */ @@ -127,7 +162,6 @@ return endPc; } - /** * @return Starting address of exception handler, relative to the code. */ @@ -135,7 +169,6 @@ return handlerPc; } - /** * @return Inclusive start index of the region where the handler is active. */ @@ -143,78 +176,58 @@ return startPc; } - /** * @param catchType the type of exception that is caught */ - public void setCatchType( final int catchType ) { + public void setCatchType(final int catchType) { this.catchType = catchType; } - /** * @param endPc end of handled block */ - public void setEndPC( final int endPc ) { + public void setEndPC(final int endPc) { this.endPc = endPc; } - /** * @param handlerPc where the actual code is */ - public void setHandlerPC( final int handlerPc ) { // TODO unused + public void setHandlerPC(final int handlerPc) { // TODO unused this.handlerPc = handlerPc; } - /** * @param startPc start of handled block */ - public void setStartPC( final int startPc ) { // TODO unused + public void setStartPC(final int startPc) { // TODO unused this.startPc = startPc; } - /** * @return String representation. */ @Override public String toString() { - return "CodeException(startPc = " + startPc + ", endPc = " + endPc + ", handlerPc = " - + handlerPc + ", catchType = " + catchType + ")"; + return "CodeException(startPc = " + startPc + ", endPc = " + endPc + ", handlerPc = " + handlerPc + ", catchType = " + catchType + ")"; } + public String toString(final ConstantPool cp) { + return toString(cp, true); + } /** + * @param cp constant pool source. + * @param verbose Output more if true. * @return String representation. */ - public String toString( final ConstantPool cp, final boolean verbose ) { + public String toString(final ConstantPool cp, final boolean verbose) { String str; if (catchType == 0) { str = "(0)"; } else { - str = Utility.compactClassName(cp.getConstantString(catchType, Const.CONSTANT_Class), false) - + (verbose ? "(" + catchType + ")" : ""); + str = Utility.compactClassName(cp.getConstantString(catchType, Const.CONSTANT_Class), false) + (verbose ? "(" + catchType + ")" : ""); } return startPc + "\t" + endPc + "\t" + handlerPc + "\t" + str; } - - - public String toString( final ConstantPool cp ) { - return toString(cp, true); - } - - - /** - * @return deep copy of this object - */ - public CodeException copy() { - try { - return (CodeException) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,126 +23,173 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class represents a chunk of Java byte code contained in a - * method. It is instantiated by the - * Attribute.readAttribute() method. A Code - * attribute contains informations about operand stack, local - * variables, byte code and the exceptions handled within this - * method. + * This class represents a chunk of Java byte code contained in a method. It is instantiated by the + * Attribute.readAttribute() method. A Code attribute contains informations about operand stack, local + * variables, byte code and the exceptions handled within this method. * - * This attribute has attributes itself, namely LineNumberTable which - * is used for debugging purposes and LocalVariableTable which - * contains information about the local variables. + * This attribute has attributes itself, namely LineNumberTable which is used for debugging purposes and + * LocalVariableTable which contains information about the local variables. * - * @see Attribute - * @see CodeException - * @see LineNumberTable + *
    + * Code_attribute {
    + *   u2 attribute_name_index;
    + *   u4 attribute_length;
    + *   u2 max_stack;
    + *   u2 max_locals;
    + *   u4 code_length;
    + *   u1 code[code_length];
    + *   u2 exception_table_length;
    + *   {
    + *     u2 start_pc;
    + *     u2 end_pc;
    + *     u2 handler_pc;
    + *     u2 catch_type;
    + *   } exception_table[exception_table_length];
    + *   u2 attributes_count;
    + *   attribute_info attributes[attributes_count];
    + * }
    + * 
    + * @see Attribute + * @see CodeException + * @see LineNumberTable * @see LocalVariableTable + * @LastModified: Feb 2023 */ public final class Code extends Attribute { - private int maxStack; // Maximum size of stack used by this method // TODO this could be made final (setter is not used) - private int maxLocals; // Number of local variables // TODO this could be made final (setter is not used) + private int maxStack; // Maximum size of stack used by this method // TODO this could be made final (setter is not used) + private int maxLocals; // Number of local variables // TODO this could be made final (setter is not used) private byte[] code; // Actual byte code private CodeException[] exceptionTable; // Table of handled exceptions private Attribute[] attributes; // or LocalVariable - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param code The source Code. */ - public Code(final Code c) { - this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c - .getExceptionTable(), c.getAttributes(), c.getConstantPool()); + public Code(final Code code) { + this(code.getNameIndex(), code.getLength(), code.getMaxStack(), code.getMaxLocals(), code.getCode(), code.getExceptionTable(), code.getAttributes(), + code.getConstantPool()); } - /** - * @param name_index Index pointing to the name Code + * @param nameIndex Index pointing to the name Code * @param length Content length in bytes * @param file Input stream - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - Code(final int name_index, final int length, final DataInput file, final ConstantPool constant_pool) - throws IOException { + Code(final int nameIndex, final int length, final DataInput file, final ConstantPool constantPool) throws IOException { // Initialize with some default values which will be overwritten later - this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, - (CodeException[]) null, (Attribute[]) null, constant_pool); - final int code_length = file.readInt(); - code = new byte[code_length]; // Read byte code + this(nameIndex, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, (CodeException[]) null, (Attribute[]) null, constantPool); + final int codeLength = Args.requireU4(file.readInt(), 1, "Code length attribute"); + code = new byte[codeLength]; // Read byte code file.readFully(code); - /* Read exception table that contains all regions where an exception - * handler is active, i.e., a try { ... } catch() block. + /* + * Read exception table that contains all regions where an exception handler is active, i.e., a try { ... } catch() + * block. */ - final int exception_table_length = file.readUnsignedShort(); - exceptionTable = new CodeException[exception_table_length]; - for (int i = 0; i < exception_table_length; i++) { + final int exceptionTableLength = file.readUnsignedShort(); + exceptionTable = new CodeException[exceptionTableLength]; + for (int i = 0; i < exceptionTableLength; i++) { exceptionTable[i] = new CodeException(file); } - /* Read all attributes, currently `LineNumberTable' and - * `LocalVariableTable' + /* + * Read all attributes, currently 'LineNumberTable' and 'LocalVariableTable' */ - final int attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - attributes[i] = Attribute.readAttribute(file, constant_pool); - } - /* Adjust length, because of setAttributes in this(), s.b. length - * is incorrect, because it didn't take the internal attributes - * into account yet! Very subtle bug, fixed in 3.1.1. + final int attributesCount = file.readUnsignedShort(); + attributes = new Attribute[attributesCount]; + for (int i = 0; i < attributesCount; i++) { + attributes[i] = Attribute.readAttribute(file, constantPool); + } + /* + * Adjust length, because of setAttributes in this(), s.b. length is incorrect, because it didn't take the internal + * attributes into account yet! Very subtle bug, fixed in 3.1.1. */ super.setLength(length); } - /** - * @param name_index Index pointing to the name Code + * @param nameIndex Index pointing to the name Code * @param length Content length in bytes * @param maxStack Maximum size of stack * @param maxLocals Number of local variables * @param code Actual byte code * @param exceptionTable of handled exceptions * @param attributes Attributes of code: LineNumber or LocalVariable - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public Code(final int name_index, final int length, final int maxStack, final int maxLocals, final byte[] code, - final CodeException[] exceptionTable, final Attribute[] attributes, final ConstantPool constant_pool) { - super(Const.ATTR_CODE, name_index, length, constant_pool); - this.maxStack = maxStack; - this.maxLocals = maxLocals; - this.code = code != null ? code : new byte[0]; - this.exceptionTable = exceptionTable != null ? exceptionTable : new CodeException[0]; - this.attributes = attributes != null ? attributes : new Attribute[0]; + public Code(final int nameIndex, final int length, final int maxStack, final int maxLocals, final byte[] code, final CodeException[] exceptionTable, + final Attribute[] attributes, final ConstantPool constantPool) { + super(Const.ATTR_CODE, nameIndex, length, constantPool); + this.maxStack = Args.requireU2(maxStack, "maxStack"); + this.maxLocals = Args.requireU2(maxLocals, "maxLocals"); + this.code = code != null ? code : Const.EMPTY_BYTE_ARRAY; + this.exceptionTable = exceptionTable != null ? exceptionTable : CodeException.EMPTY_CODE_EXCEPTION_ARRAY; + Args.requireU2(this.exceptionTable.length, "exceptionTable.length"); + this.attributes = attributes != null ? attributes : EMPTY_ARRAY; super.setLength(calculateLength()); // Adjust length } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitCode(this); } + /** + * @return the full size of this code attribute, minus its first 6 bytes, including the size of all its contained + * attributes + */ + private int calculateLength() { + int len = 0; + if (attributes != null) { + for (final Attribute attribute : attributes) { + len += attribute.getLength() + 6 /* attribute header size */; + } + } + return len + getInternalLength(); + } + + /** + * @return deep copy of this attribute + * + * @param constantPool the constant pool to duplicate + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final Code c = (Code) clone(); + if (code != null) { + c.code = code.clone(); + } + c.setConstantPool(constantPool); + c.exceptionTable = new CodeException[exceptionTable.length]; + Arrays.setAll(c.exceptionTable, i -> exceptionTable[i].copy()); + c.attributes = new Attribute[attributes.length]; + Arrays.setAll(c.attributes, i -> attributes[i].copy(constantPool)); + return c; + } /** * Dump code attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(maxStack); file.writeShort(maxLocals); @@ -159,7 +205,6 @@ } } - /** * @return Collection of code attributes. * @see Attribute @@ -168,6 +213,31 @@ return attributes; } + /** + * @return Actual byte code of the method. + */ + public byte[] getCode() { + return code; + } + + /** + * @return Table of handled exceptions. + * @see CodeException + */ + public CodeException[] getExceptionTable() { + return exceptionTable; + } + + /** + * @return the internal length of this code attribute (minus the first 6 bytes) and excluding all its attributes + */ + private int getInternalLength() { + return 2 /* maxStack */ + 2 /* maxLocals */ + 4 /* code length */ + + code.length /* byte-code */ + + 2 /* exception-table length */ + + 8 * (exceptionTable == null ? 0 : exceptionTable.length) /* exception table */ + + 2 /* attributes count */; + } /** * @return LineNumberTable of Code, if it has one @@ -181,7 +251,6 @@ return null; } - /** * @return LocalVariableTable of Code, if it has one */ @@ -194,24 +263,6 @@ return null; } - - /** - * @return Actual byte code of the method. - */ - public byte[] getCode() { - return code; - } - - - /** - * @return Table of handled exceptions. - * @see CodeException - */ - public CodeException[] getExceptionTable() { - return exceptionTable; - } - - /** * @return Number of local variables. */ @@ -219,7 +270,6 @@ return maxLocals; } - /** * @return Maximum size of stack used by this method. */ @@ -227,86 +277,62 @@ return maxStack; } - - /** - * @return the internal length of this code attribute (minus the first 6 bytes) - * and excluding all its attributes - */ - private int getInternalLength() { - return 2 /*maxStack*/+ 2 /*maxLocals*/+ 4 /*code length*/ - + code.length /*byte-code*/ - + 2 /*exception-table length*/ - + 8 * (exceptionTable == null ? 0 : exceptionTable.length) /* exception table */ - + 2 /* attributes count */; - } - - - /** - * @return the full size of this code attribute, minus its first 6 bytes, - * including the size of all its contained attributes - */ - private int calculateLength() { - int len = 0; - if (attributes != null) { - for (final Attribute attribute : attributes) { - len += attribute.getLength() + 6 /*attribute header size*/; - } - } - return len + getInternalLength(); - } - - /** * @param attributes the attributes to set for this Code */ - public void setAttributes( final Attribute[] attributes ) { - this.attributes = attributes != null ? attributes : new Attribute[0]; + public void setAttributes(final Attribute[] attributes) { + this.attributes = attributes != null ? attributes : EMPTY_ARRAY; super.setLength(calculateLength()); // Adjust length } - /** * @param code byte code */ - public void setCode( final byte[] code ) { - this.code = code != null ? code : new byte[0]; + public void setCode(final byte[] code) { + this.code = code != null ? code : Const.EMPTY_BYTE_ARRAY; super.setLength(calculateLength()); // Adjust length } - /** * @param exceptionTable exception table */ - public void setExceptionTable( final CodeException[] exceptionTable ) { - this.exceptionTable = exceptionTable != null ? exceptionTable : new CodeException[0]; + public void setExceptionTable(final CodeException[] exceptionTable) { + this.exceptionTable = exceptionTable != null ? exceptionTable : CodeException.EMPTY_CODE_EXCEPTION_ARRAY; super.setLength(calculateLength()); // Adjust length } - /** * @param maxLocals maximum number of local variables */ - public void setMaxLocals( final int maxLocals ) { + public void setMaxLocals(final int maxLocals) { this.maxLocals = maxLocals; } - /** * @param maxStack maximum stack size */ - public void setMaxStack( final int maxStack ) { + public void setMaxStack(final int maxStack) { this.maxStack = maxStack; } + /** + * @return String representation of code chunk. + */ + @Override + public String toString() { + return toString(true); + } /** + * Converts this object to a String. + * + * @param verbose Provides verbose output when true. * @return String representation of code chunk. */ - public String toString( final boolean verbose ) { + public String toString(final boolean verbose) { final StringBuilder buf = new StringBuilder(100); // CHECKSTYLE IGNORE MagicNumber - buf.append("Code(maxStack = ").append(maxStack).append(", maxLocals = ").append( - maxLocals).append(", code_length = ").append(code.length).append(")\n").append( - Utility.codeToString(code, super.getConstantPool(), 0, -1, verbose)); + buf.append("Code(maxStack = ").append(maxStack).append(", maxLocals = ").append(maxLocals).append(", code_length = ").append(code.length).append(")\n") + .append(Utility.codeToString(code, super.getConstantPool(), 0, -1, verbose)); if (exceptionTable.length > 0) { buf.append("\nException handler(s) = \n").append("From\tTo\tHandler\tType\n"); for (final CodeException exception : exceptionTable) { @@ -322,38 +348,4 @@ } return buf.toString(); } - - - /** - * @return String representation of code chunk. - */ - @Override - public String toString() { - return toString(true); - } - - - /** - * @return deep copy of this attribute - * - * @param _constant_pool the constant pool to duplicate - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final Code c = (Code) clone(); - if (code != null) { - c.code = new byte[code.length]; - System.arraycopy(code, 0, c.code, 0, code.length); - } - c.setConstantPool(_constant_pool); - c.exceptionTable = new CodeException[exceptionTable.length]; - for (int i = 0; i < exceptionTable.length; i++) { - c.exceptionTable[i] = exceptionTable[i].copy(); - } - c.attributes = new Attribute[attributes.length]; - for (int i = 0; i < attributes.length; i++) { - c.attributes[i] = attributes[i].copy(_constant_pool); - } - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,24 +28,23 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a (external) class. + * This class is derived from the abstract {@link Constant} and represents a reference to a (external) class. * - * @see Constant + * @see Constant */ public final class ConstantClass extends Constant implements ConstantObject { private int nameIndex; // Identical to ConstantString except for the name - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantClass(final ConstantClass c) { this(c.getNameIndex()); } - /** * Constructs an instance from file data. * @@ -56,30 +55,25 @@ this(dataInput.readUnsignedShort()); } - /** - * @param nameIndex Name index in constant pool. Should refer to a - * ConstantUtf8. + * @param nameIndex Name index in constant pool. Should refer to a ConstantUtf8. */ public ConstantClass(final int nameIndex) { super(Const.CONSTANT_Class); this.nameIndex = nameIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantClass(this); } - /** * Dumps constant class to file stream in binary format. * @@ -87,44 +81,40 @@ * @throws IOException if an I/O error occurs writing to the DataOutputStream. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(nameIndex); } - /** - * @return Name index in constant pool of class name. + * @return dereferenced string */ - public int getNameIndex() { - return nameIndex; + public String getBytes(final ConstantPool cp) { + return (String) getConstantValue(cp); } - /** - * @param nameIndex the name index in the constant pool of this Constant Class + * @return String object */ - public void setNameIndex( final int nameIndex ) { - this.nameIndex = nameIndex; + @Override + public Object getConstantValue(final ConstantPool cp) { + return cp.getConstantUtf8(nameIndex).getBytes(); } - - /** @return String object + /** + * @return Name index in constant pool of class name. */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(nameIndex, Const.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); + public int getNameIndex() { + return nameIndex; } - - /** @return dereferenced string + /** + * @param nameIndex the name index in the constant pool of this Constant Class */ - public String getBytes( final ConstantPool cp ) { - return (String) getConstantValue(cp); + public void setNameIndex(final int nameIndex) { + this.nameIndex = nameIndex; } - /** * @return String representation. */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,8 +26,7 @@ import com.sun.org.apache.bcel.internal.Const; /** - * Abstract super class for Fieldref, Methodref, InterfaceMethodref and - * InvokeDynamic constants. + * Abstract super class for Fieldref, Methodref, InterfaceMethodref and InvokeDynamic constants. * * @see ConstantFieldref * @see ConstantMethodref @@ -42,71 +41,76 @@ */ // Note that this field is used to store the // bootstrap_method_attr_index of a ConstantInvokeDynamic. - private int class_index; + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected int class_index; // TODO make private (has getter & setter) // This field has the same meaning for all subclasses. - private int name_and_type_index; /** - * Initialize from another object. + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - public ConstantCP(final ConstantCP c) { - this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); - } - + @java.lang.Deprecated + protected int name_and_type_index; // TODO make private (has getter & setter) /** * Initialize instance from file data. * - * @param tag Constant type tag + * @param tag Constant type tag * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantCP(final byte tag, final DataInput file) throws IOException { this(tag, file.readUnsignedShort(), file.readUnsignedShort()); } - /** - * @param class_index Reference to the class containing the field - * @param name_and_type_index and the field signature + * @param classIndex Reference to the class containing the field + * @param nameAndTypeIndex and the field signature */ - protected ConstantCP(final byte tag, final int class_index, final int name_and_type_index) { + protected ConstantCP(final byte tag, final int classIndex, final int nameAndTypeIndex) { super(tag); - this.class_index = class_index; - this.name_and_type_index = name_and_type_index; + this.class_index = classIndex; + this.name_and_type_index = nameAndTypeIndex; } + /** + * Initialize from another object. + * + * @param c Source to copy. + */ + public ConstantCP(final ConstantCP c) { + this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); + } /** * Dump constant field reference to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public final void dump( final DataOutputStream file ) throws IOException { + public final void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(class_index); file.writeShort(name_and_type_index); } - /** - * @return Reference (index) to class this constant refers to. + * @return Class this field belongs to. */ - public final int getClassIndex() { - return class_index; + public String getClass(final ConstantPool cp) { + return cp.constantToString(class_index, Const.CONSTANT_Class); } - /** - * @param class_index points to Constant_class + * @return Reference (index) to class this constant refers to. */ - public final void setClassIndex( final int class_index ) { - this.class_index = class_index; + public final int getClassIndex() { + return class_index; } - /** * @return Reference (index) to signature of the field. */ @@ -114,31 +118,27 @@ return name_and_type_index; } - /** - * @param name_and_type_index points to Constant_NameAndType + * @param classIndex points to Constant_class */ - public final void setNameAndTypeIndex( final int name_and_type_index ) { - this.name_and_type_index = name_and_type_index; + public final void setClassIndex(final int classIndex) { + this.class_index = classIndex; } - /** - * @return Class this field belongs to. + * @param nameAndTypeIndex points to Constant_NameAndType */ - public String getClass( final ConstantPool cp ) { - return cp.constantToString(class_index, Const.CONSTANT_Class); + public final void setNameAndTypeIndex(final int nameAndTypeIndex) { + this.name_and_type_index = nameAndTypeIndex; } - /** * @return String representation. * - * not final as ConstantInvokeDynamic needs to modify + * not final as ConstantInvokeDynamic needs to modify */ @Override public String toString() { - return super.toString() + "(class_index = " + class_index + ", name_and_type_index = " - + name_and_type_index + ")"; + return super.toString() + "(class_index = " + class_index + ", name_and_type_index = " + name_and_type_index + ")"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,8 +27,7 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a Double object. + * This class is derived from the abstract {@link Constant} and represents a reference to a Double object. * * @see Constant * @LastModified: Jun 2019 @@ -37,61 +36,56 @@ private double bytes; - - /** - * @param bytes Data - */ - public ConstantDouble(final double bytes) { - super(Const.CONSTANT_Double); - this.bytes = bytes; - } - - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantDouble(final ConstantDouble c) { this(c.getBytes()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantDouble(final DataInput file) throws IOException { this(file.readDouble()); } + /** + * @param bytes Data + */ + public ConstantDouble(final double bytes) { + super(Const.CONSTANT_Double); + this.bytes = bytes; + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantDouble(this); } - /** * Dump constant double to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeDouble(bytes); } - /** * @return data, i.e., 8 bytes. */ @@ -99,15 +93,21 @@ return bytes; } + /** + * @return Double object + */ + @Override + public Object getConstantValue(final ConstantPool cp) { + return Double.valueOf(bytes); + } /** * @param bytes the raw bytes that represent the double value */ - public void setBytes( final double bytes ) { + public void setBytes(final double bytes) { this.bytes = bytes; } - /** * @return String representation. */ @@ -115,12 +115,4 @@ public String toString() { return super.toString() + "(bytes = " + bytes + ")"; } - - - /** @return Double object - */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - return bytes; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDynamic.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDynamic.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDynamic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDynamic.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,18 +27,20 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a dynamically computed constant. + * This class is derived from the abstract {@link Constant} and represents a reference to a dynamically computed + * constant. * - * @see Constant - * @see - * Change request for JEP 309 + * @see Constant + * @see Change request for JEP + * 309 * @since 6.3 */ public final class ConstantDynamic extends ConstantCP { /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantDynamic(final ConstantDynamic c) { this(c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex()); @@ -49,39 +51,37 @@ * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantDynamic(final DataInput file) throws IOException { this(file.readShort(), file.readShort()); } - public ConstantDynamic(final int bootstrap_method_attr_index, final int name_and_type_index) { - super(Const.CONSTANT_Dynamic, bootstrap_method_attr_index, name_and_type_index); + public ConstantDynamic(final int bootstrapMethodAttrIndex, final int nameAndTypeIndex) { + super(Const.CONSTANT_Dynamic, bootstrapMethodAttrIndex, nameAndTypeIndex); } /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantDynamic(this); } /** * @return Reference (index) to bootstrap method this constant refers to. * - * Note that this method is a functional duplicate of getClassIndex - * for use by ConstantInvokeDynamic. + * Note that this method is a functional duplicate of getClassIndex for use by ConstantInvokeDynamic. * @since 6.0 */ public int getBootstrapMethodAttrIndex() { - return super.getClassIndex(); // AKA bootstrap_method_attr_index + return super.getClassIndex(); // AKA bootstrap_method_attr_index } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,47 +28,44 @@ /** * This class represents a constant pool reference to a field. - * */ public final class ConstantFieldref extends ConstantCP { /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantFieldref(final ConstantFieldref c) { super(Const.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex()); } - /** * Initialize instance from input data. * * @param input input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantFieldref(final DataInput input) throws IOException { super(Const.CONSTANT_Fieldref, input); } - /** - * @param class_index Reference to the class containing the Field - * @param name_and_type_index and the Field signature + * @param classIndex Reference to the class containing the Field + * @param nameAndTypeIndex and the Field signature */ - public ConstantFieldref(final int class_index, final int name_and_type_index) { - super(Const.CONSTANT_Fieldref, class_index, name_and_type_index); + public ConstantFieldref(final int classIndex, final int nameAndTypeIndex) { + super(Const.CONSTANT_Fieldref, classIndex, nameAndTypeIndex); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of Fields, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of Fields, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantFieldref(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,8 +27,7 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a float object. + * This class is derived from the abstract {@link Constant} and represents a reference to a float object. * * @see Constant * @LastModified: Jun 2019 @@ -37,62 +36,57 @@ private float bytes; - - /** - * @param bytes Data - */ - public ConstantFloat(final float bytes) { - super(Const.CONSTANT_Float); - this.bytes = bytes; - } - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. */ public ConstantFloat(final ConstantFloat c) { this(c.getBytes()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantFloat(final DataInput file) throws IOException { this(file.readFloat()); } + /** + * @param bytes Data + */ + public ConstantFloat(final float bytes) { + super(Const.CONSTANT_Float); + this.bytes = bytes; + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantFloat(this); } - /** * Dump constant float to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeFloat(bytes); } - /** * @return data, i.e., 4 bytes. */ @@ -100,15 +94,21 @@ return bytes; } + /** + * @return Float object + */ + @Override + public Object getConstantValue(final ConstantPool cp) { + return Float.valueOf(bytes); + } /** * @param bytes the raw bytes that represent this float */ - public void setBytes( final float bytes ) { + public void setBytes(final float bytes) { this.bytes = bytes; } - /** * @return String representation. */ @@ -116,12 +116,4 @@ public String toString() { return super.toString() + "(bytes = " + bytes + ")"; } - - - /** @return Float object - */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - return bytes; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,8 +27,7 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to an int object. + * This class is derived from the abstract {@link Constant} and represents a reference to an int object. * * @see Constant * @LastModified: Jun 2019 @@ -37,61 +36,56 @@ private int bytes; - - /** - * @param bytes Data - */ - public ConstantInteger(final int bytes) { - super(Const.CONSTANT_Integer); - this.bytes = bytes; - } - - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantInteger(final ConstantInteger c) { this(c.getBytes()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantInteger(final DataInput file) throws IOException { this(file.readInt()); } + /** + * @param bytes Data + */ + public ConstantInteger(final int bytes) { + super(Const.CONSTANT_Integer); + this.bytes = bytes; + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantInteger(this); } - /** * Dump constant integer to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeInt(bytes); } - /** * @return data, i.e., 4 bytes. */ @@ -99,15 +93,21 @@ return bytes; } + /** + * @return Integer object + */ + @Override + public Object getConstantValue(final ConstantPool cp) { + return Integer.valueOf(bytes); + } /** * @param bytes the raw bytes that represent this integer */ - public void setBytes( final int bytes ) { + public void setBytes(final int bytes) { this.bytes = bytes; } - /** * @return String representation. */ @@ -115,12 +115,4 @@ public String toString() { return super.toString() + "(bytes = " + bytes + ")"; } - - - /** @return Integer object - */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - return Integer.valueOf(bytes); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,47 +28,44 @@ /** * This class represents a constant pool reference to an interface method. - * */ public final class ConstantInterfaceMethodref extends ConstantCP { /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantInterfaceMethodref(final ConstantInterfaceMethodref c) { super(Const.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex()); } - /** * Initialize instance from input data. * * @param input input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantInterfaceMethodref(final DataInput input) throws IOException { super(Const.CONSTANT_InterfaceMethodref, input); } - /** - * @param class_index Reference to the class containing the method - * @param name_and_type_index and the method signature + * @param classIndex Reference to the class containing the method + * @param nameAndTypeIndex and the method signature */ - public ConstantInterfaceMethodref(final int class_index, final int name_and_type_index) { - super(Const.CONSTANT_InterfaceMethodref, class_index, name_and_type_index); + public ConstantInterfaceMethodref(final int classIndex, final int nameAndTypeIndex) { + super(Const.CONSTANT_InterfaceMethodref, classIndex, nameAndTypeIndex); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantInterfaceMethodref(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInvokeDynamic.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,61 +27,57 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a invoke dynamic. + * This class is derived from the abstract {@link Constant} and represents a reference to a invoke dynamic. * - * @see Constant - * @see - * The CONSTANT_InvokeDynamic_info Structure in The Java Virtual Machine Specification + * @see Constant + * @see The + * CONSTANT_InvokeDynamic_info Structure in The Java Virtual Machine Specification * @since 6.0 */ public final class ConstantInvokeDynamic extends ConstantCP { /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantInvokeDynamic(final ConstantInvokeDynamic c) { this(c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantInvokeDynamic(final DataInput file) throws IOException { - this(file.readShort(), file.readShort()); + this(file.readUnsignedShort(), file.readUnsignedShort()); } - - public ConstantInvokeDynamic(final int bootstrap_method_attr_index, final int name_and_type_index) { - super(Const.CONSTANT_InvokeDynamic, bootstrap_method_attr_index, name_and_type_index); + public ConstantInvokeDynamic(final int bootstrapMethodAttrIndex, final int nameAndTypeIndex) { + super(Const.CONSTANT_InvokeDynamic, bootstrapMethodAttrIndex, nameAndTypeIndex); } - /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantInvokeDynamic(this); } /** * @return Reference (index) to bootstrap method this constant refers to. * - * Note that this method is a functional duplicate of getClassIndex - * for use by ConstantInvokeDynamic. + * Note that this method is a functional duplicate of getClassIndex for use by ConstantInvokeDynamic. * @since 6.0 */ public int getBootstrapMethodAttrIndex() { - return super.getClassIndex(); // AKA bootstrap_method_attr_index + return super.getClassIndex(); // AKA bootstrap_method_attr_index } /** diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java 2023-10-06 05:33:33.000000000 +0000 @@ -39,81 +39,24 @@ private static BCELComparator bcelComparator = new BCELComparator() { @Override - public boolean equals( final Object o1, final Object o2 ) { + public boolean equals(final Object o1, final Object o2) { final Constant THIS = (Constant) o1; final Constant THAT = (Constant) o2; return Objects.equals(THIS.toString(), THAT.toString()); } - @Override - public int hashCode( final Object o ) { + public int hashCode(final Object o) { final Constant THIS = (Constant) o; return THIS.toString().hashCode(); } }; - /* In fact this tag is redundant since we can distinguish different - * `Constant' objects by their type, i.e., via `instanceof'. In some - * places we will use the tag for switch()es anyway. - * - * First, we want match the specification as closely as possible. Second we - * need the tag as an index to select the corresponding class name from the - * `CONSTANT_NAMES' array. - */ - private byte tag; - - Constant(final byte tag) { - this.tag = tag; - } - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public abstract void accept( Visitor v ); - - public abstract void dump( DataOutputStream file ) throws IOException; - - /** - * @return Tag of constant, i.e., its type. No setTag() method to avoid - * confusion. - */ - public final byte getTag() { - return tag; - } - - /** - * @return String representation. - */ - @Override - public String toString() { - return Const.getConstantName(tag) + "[" + tag + "]"; - } - /** - * @return deep copy of this constant + * @return Comparison strategy object */ - public Constant copy() { - try { - return (Constant) super.clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - throw new Error("Clone Not Supported"); // never happens - } + public static BCELComparator getComparator() { + return bcelComparator; } /** @@ -168,39 +111,95 @@ } /** - * @return Comparison strategy object + * @param comparator Comparison strategy object */ - public static BCELComparator getComparator() { - return bcelComparator; + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; } + /* + * In fact this tag is redundant since we can distinguish different 'Constant' objects by their type, i.e., via + * 'instanceof'. In some places we will use the tag for switch()es anyway. + * + * First, we want match the specification as closely as possible. Second we need the tag as an index to select the + * corresponding class name from the 'CONSTANT_NAMES' array. + */ /** - * @param comparator Comparison strategy object + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; + @java.lang.Deprecated + protected byte tag; // TODO should be private & final + + Constant(final byte tag) { + this.tag = tag; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public abstract void accept(Visitor v); + + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } /** - * Returns value as defined by given BCELComparator strategy. - * By default two Constant objects are said to be equal when + * @return deep copy of this constant + */ + public Constant copy() { + try { + return (Constant) super.clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } + + public abstract void dump(DataOutputStream file) throws IOException; + + /** + * Returns value as defined by given BCELComparator strategy. By default two Constant objects are said to be equal when * the result of toString() is equal. * - * @see java.lang.Object#equals(java.lang.Object) + * @see Object#equals(Object) */ @Override - public boolean equals( final Object obj ) { + public boolean equals(final Object obj) { return bcelComparator.equals(this, obj); } /** - * Returns value as defined by given BCELComparator strategy. - * By default return the hashcode of the result of toString(). + * @return Tag of constant, i.e., its type. No setTag() method to avoid confusion. + */ + public final byte getTag() { + return tag; + } + + /** + * Returns value as defined by given BCELComparator strategy. By default return the hashcode of the result of + * toString(). * - * @see java.lang.Object#hashCode() + * @see Object#hashCode() */ @Override public int hashCode() { return bcelComparator.hashCode(this); } + + /** + * @return String representation. + */ + @Override + public String toString() { + return Const.getConstantName(tag) + "[" + tag + "]"; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,8 +27,7 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a long object. + * This class is derived from the abstract {@link Constant} and represents a reference to a long object. * * @see Constant * @LastModified: Jan 2020 @@ -37,61 +36,56 @@ private long bytes; - - /** - * @param bytes Data - */ - public ConstantLong(final long bytes) { - super(Const.CONSTANT_Long); - this.bytes = bytes; - } - - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantLong(final ConstantLong c) { this(c.getBytes()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantLong(final DataInput file) throws IOException { this(file.readLong()); } + /** + * @param bytes Data + */ + public ConstantLong(final long bytes) { + super(Const.CONSTANT_Long); + this.bytes = bytes; + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantLong(this); } - /** * Dump constant long to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeLong(bytes); } - /** * @return data, i.e., 8 bytes. */ @@ -99,15 +93,21 @@ return bytes; } + /** + * @return Long object + */ + @Override + public Object getConstantValue(final ConstantPool cp) { + return Long.valueOf(bytes); + } /** * @param bytes the raw bytes that represent this long */ - public void setBytes( final long bytes ) { + public void setBytes(final long bytes) { this.bytes = bytes; } - /** * @return String representation. */ @@ -115,12 +115,4 @@ public String toString() { return super.toString() + "(bytes = " + bytes + ")"; } - - - /** @return Long object - */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - return bytes; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodHandle.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,10 +28,9 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a method handle. + * This class is derived from the abstract {@link Constant} and represents a reference to a method handle. * - * @see Constant + * @see Constant * @since 6.0 */ public final class ConstantMethodHandle extends Constant { @@ -39,86 +38,76 @@ private int referenceKind; private int referenceIndex; - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantMethodHandle(final ConstantMethodHandle c) { this(c.getReferenceKind(), c.getReferenceIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantMethodHandle(final DataInput file) throws IOException { this(file.readUnsignedByte(), file.readUnsignedShort()); } - - public ConstantMethodHandle(final int reference_kind, final int reference_index) { + public ConstantMethodHandle(final int referenceKind, final int referenceIndex) { super(Const.CONSTANT_MethodHandle); - this.referenceKind = reference_kind; - this.referenceIndex = reference_index; + this.referenceKind = referenceKind; + this.referenceIndex = referenceIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantMethodHandle(this); } - /** * Dump method kind and index to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeByte(referenceKind); file.writeShort(referenceIndex); } + public int getReferenceIndex() { + return referenceIndex; + } public int getReferenceKind() { return referenceKind; } - - public void setReferenceKind(final int reference_kind) { - this.referenceKind = reference_kind; - } - - - public int getReferenceIndex() { - return referenceIndex; + public void setReferenceIndex(final int referenceIndex) { + this.referenceIndex = referenceIndex; } - - public void setReferenceIndex(final int reference_index) { - this.referenceIndex = reference_index; + public void setReferenceKind(final int referenceKind) { + this.referenceKind = referenceKind; } - /** * @return String representation */ @Override public String toString() { - return super.toString() + "(referenceKind = " + referenceKind + - ", referenceIndex = " + referenceIndex + ")"; + return super.toString() + "(referenceKind = " + referenceKind + ", referenceIndex = " + referenceIndex + ")"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,47 +28,44 @@ /** * This class represents a constant pool reference to a method. - * */ public final class ConstantMethodref extends ConstantCP { /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantMethodref(final ConstantMethodref c) { super(Const.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex()); } - /** * Initialize instance from input data. * * @param input input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantMethodref(final DataInput input) throws IOException { super(Const.CONSTANT_Methodref, input); } - /** - * @param class_index Reference to the class containing the method - * @param name_and_type_index and the method signature + * @param classIndex Reference to the class containing the method + * @param nameAndTypeIndex and the method signature */ - public ConstantMethodref(final int class_index, final int name_and_type_index) { - super(Const.CONSTANT_Methodref, class_index, name_and_type_index); + public ConstantMethodref(final int classIndex, final int nameAndTypeIndex) { + super(Const.CONSTANT_Methodref, classIndex, nameAndTypeIndex); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantMethodref(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodType.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,78 +28,70 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a method type. + * This class is derived from the abstract {@link Constant} and represents a reference to a method type. * - * @see Constant + * @see Constant * @since 6.0 */ public final class ConstantMethodType extends Constant { private int descriptorIndex; - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantMethodType(final ConstantMethodType c) { this(c.getDescriptorIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantMethodType(final DataInput file) throws IOException { this(file.readUnsignedShort()); } - - public ConstantMethodType(final int descriptor_index) { + public ConstantMethodType(final int descriptorIndex) { super(Const.CONSTANT_MethodType); - this.descriptorIndex = descriptor_index; + this.descriptorIndex = descriptorIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantMethodType(this); } - /** * Dump name and signature index to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(descriptorIndex); } - public int getDescriptorIndex() { return descriptorIndex; } - - public void setDescriptorIndex(final int descriptor_index) { - this.descriptorIndex = descriptor_index; + public void setDescriptorIndex(final int descriptorIndex) { + this.descriptorIndex = descriptorIndex; } - /** * @return String representation */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantModule.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,106 +28,98 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a module. + * This class is derived from the abstract {@link Constant} and represents a reference to a module. * - *

    Note: Early access Java 9 support- currently subject to change

    + *

    + * Note: Early access Java 9 support- currently subject to change + *

    * - * @see Constant + * @see Constant * @since 6.1 */ public final class ConstantModule extends Constant implements ConstantObject { private int nameIndex; - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantModule(final ConstantModule c) { this(c.getNameIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantModule(final DataInput file) throws IOException { this(file.readUnsignedShort()); } - /** - * @param nameIndex Name index in constant pool. Should refer to a - * ConstantUtf8. + * @param nameIndex Name index in constant pool. Should refer to a ConstantUtf8. */ public ConstantModule(final int nameIndex) { super(Const.CONSTANT_Module); this.nameIndex = nameIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantModule(this); } - /** * Dump constant module to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(nameIndex); } - /** - * @return Name index in constant pool of module name. + * @return dereferenced string */ - public int getNameIndex() { - return nameIndex; + public String getBytes(final ConstantPool cp) { + return (String) getConstantValue(cp); } - /** - * @param nameIndex the name index in the constant pool of this Constant Module + * @return String object */ - public void setNameIndex( final int nameIndex ) { - this.nameIndex = nameIndex; + @Override + public Object getConstantValue(final ConstantPool cp) { + return cp.getConstantUtf8(nameIndex).getBytes(); } - - /** @return String object + /** + * @return Name index in constant pool of module name. */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(nameIndex, Const.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); + public int getNameIndex() { + return nameIndex; } - - /** @return dereferenced string + /** + * @param nameIndex the name index in the constant pool of this Constant Module */ - public String getBytes( final ConstantPool cp ) { - return (String) getConstantValue(cp); + public void setNameIndex(final int nameIndex) { + this.nameIndex = nameIndex; } - /** * @return String representation. */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,37 +28,35 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to the name and signature - * of a field or method. + * This class is derived from the abstract {@link Constant} and represents a reference to the name and signature of a + * field or method. * - * @see Constant + * @see Constant */ public final class ConstantNameAndType extends Constant { private int nameIndex; // Name of field/method private int signatureIndex; // and its signature. - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantNameAndType(final ConstantNameAndType c) { this(c.getNameIndex(), c.getSignatureIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantNameAndType(final DataInput file) throws IOException { this(file.readUnsignedShort(), file.readUnsignedShort()); } - /** * @param nameIndex Name of field/method * @param signatureIndex and its signature @@ -69,33 +67,36 @@ this.signatureIndex = signatureIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantNameAndType(this); } - /** * Dump name and signature index to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(nameIndex); file.writeShort(signatureIndex); } + /** + * @return name + */ + public String getName(final ConstantPool cp) { + return cp.constantToString(getNameIndex(), Const.CONSTANT_Utf8); + } /** * @return Name index in constant pool of field/method name. @@ -104,14 +105,13 @@ return nameIndex; } - - /** @return name + /** + * @return signature */ - public String getName( final ConstantPool cp ) { - return cp.constantToString(getNameIndex(), Const.CONSTANT_Utf8); + public String getSignature(final ConstantPool cp) { + return cp.constantToString(getSignatureIndex(), Const.CONSTANT_Utf8); } - /** * @return Index in constant pool of field/method signature. */ @@ -119,36 +119,25 @@ return signatureIndex; } - - /** @return signature - */ - public String getSignature( final ConstantPool cp ) { - return cp.constantToString(getSignatureIndex(), Const.CONSTANT_Utf8); - } - - /** * @param nameIndex the name index of this constant */ - public void setNameIndex( final int nameIndex ) { + public void setNameIndex(final int nameIndex) { this.nameIndex = nameIndex; } - /** * @param signatureIndex the signature index in the constant pool of this type */ - public void setSignatureIndex( final int signatureIndex ) { + public void setSignatureIndex(final int signatureIndex) { this.signatureIndex = signatureIndex; } - /** * @return String representation */ @Override public String toString() { - return super.toString() + "(nameIndex = " + nameIndex + ", signatureIndex = " - + signatureIndex + ")"; + return super.toString() + "(nameIndex = " + nameIndex + ", signatureIndex = " + signatureIndex + ")"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,14 +22,14 @@ package com.sun.org.apache.bcel.internal.classfile; /** - * This interface denotes those constants that have a "natural" value, - * such as ConstantLong, ConstantString, etc.. + * This interface denotes those constants that have a "natural" value, such as ConstantLong, ConstantString, etc.. * - * @see Constant + * @see Constant */ public interface ConstantObject { - /** @return object representing the constant, e.g., Long for ConstantLong + /** + * @return object representing the constant, e.g., Long for ConstantLong */ - Object getConstantValue( ConstantPool cp ); + Object getConstantValue(ConstantPool cp); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPackage.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,106 +28,98 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a package. + * This class is derived from the abstract {@link Constant} and represents a reference to a package. * - *

    Note: Early access Java 9 support- currently subject to change

    + *

    + * Note: Early access Java 9 support- currently subject to change + *

    * - * @see Constant + * @see Constant * @since 6.1 */ public final class ConstantPackage extends Constant implements ConstantObject { private int nameIndex; - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantPackage(final ConstantPackage c) { this(c.getNameIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantPackage(final DataInput file) throws IOException { this(file.readUnsignedShort()); } - /** - * @param nameIndex Name index in constant pool. Should refer to a - * ConstantUtf8. + * @param nameIndex Name index in constant pool. Should refer to a ConstantUtf8. */ public ConstantPackage(final int nameIndex) { super(Const.CONSTANT_Package); this.nameIndex = nameIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantPackage(this); } - /** * Dump constant package to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(nameIndex); } - /** - * @return Name index in constant pool of package name. + * @return dereferenced string */ - public int getNameIndex() { - return nameIndex; + public String getBytes(final ConstantPool cp) { + return (String) getConstantValue(cp); } - /** - * @param nameIndex the name index in the constant pool of this Constant Package + * @return String object */ - public void setNameIndex( final int nameIndex ) { - this.nameIndex = nameIndex; + @Override + public Object getConstantValue(final ConstantPool cp) { + return cp.getConstantUtf8(nameIndex).getBytes(); } - - /** @return String object + /** + * @return Name index in constant pool of package name. */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(nameIndex, Const.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); + public int getNameIndex() { + return nameIndex; } - - /** @return dereferenced string + /** + * @param nameIndex the name index in the constant pool of this Constant Package */ - public String getBytes( final ConstantPool cp ) { - return (String) getConstantValue(cp); + public void setNameIndex(final int nameIndex) { + this.nameIndex = nameIndex; } - /** * @return String representation. */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,23 +23,49 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; import com.sun.org.apache.bcel.internal.Const; -import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; /** - * This class represents the constant pool, i.e., a table of constants, of - * a parsed classfile. It may contain null references, due to the JVM - * specification that skips an entry after an 8-byte constant (double, - * long) entry. Those interested in generating constant pools - * programatically should see - * ConstantPoolGen. - - * @see Constant - * @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen - * @LastModified: June 2022 + * This class represents the constant pool, i.e., a table of constants, of a parsed classfile. It may contain null references, due to the JVM specification that + * skips an entry after an 8-byte constant (double, long) entry. Those interested in generating constant pools programmatically should see + * ConstantPoolGen. + * + * @see Constant + * @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen + * @LastModified: Feb 2023 */ -public class ConstantPool implements Cloneable, Node { +public class ConstantPool implements Cloneable, Node, Iterable { + + private static String escape(final String str) { + final int len = str.length(); + final StringBuilder buf = new StringBuilder(len + 5); + final char[] ch = str.toCharArray(); + for (int i = 0; i < len; i++) { + switch (ch[i]) { + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + case '\t': + buf.append("\\t"); + break; + case '\b': + buf.append("\\b"); + break; + case '"': + buf.append("\\\""); + break; + default: + buf.append(ch[i]); + } + } + return buf.toString(); + } private Constant[] constantPool; @@ -54,182 +80,166 @@ * Reads constants from given input stream. * * @param input Input stream - * @throws IOException - * @throws ClassFormatException + * @throws IOException if problem in readUnsignedShort or readConstant */ - public ConstantPool(final DataInput input) throws IOException, ClassFormatException { + public ConstantPool(final DataInput input) throws IOException { byte tag; - final int constant_pool_count = input.readUnsignedShort(); - constantPool = new Constant[constant_pool_count]; - /* constantPool[0] is unused by the compiler and may be used freely - * by the implementation. + final int constantPoolCount = input.readUnsignedShort(); + constantPool = new Constant[constantPoolCount]; + /* + * constantPool[0] is unused by the compiler and may be used freely by the implementation. */ - for (int i = 1; i < constant_pool_count; i++) { + for (int i = 1; i < constantPoolCount; i++) { constantPool[i] = Constant.readConstant(input); - /* Quote from the JVM specification: - * "All eight byte constants take up two spots in the constant pool. - * If this is the n'th byte in the constant pool, then the next item - * will be numbered n+2" + /* + * Quote from the JVM specification: "All eight byte constants take up two spots in the constant pool. If this is the n'th byte in the constant + * pool, then the next item will be numbered n+2" * * Thus we have to increment the index counter. */ tag = constantPool[i].getTag(); - if ((tag == Const.CONSTANT_Double) || (tag == Const.CONSTANT_Long)) { + if (tag == Const.CONSTANT_Double || tag == Const.CONSTANT_Long) { i++; } } } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., the hierarchy of methods, fields, + * attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantPool(this); } /** * Resolves constant to a string representation. * - * @param c Constant to be printed + * @param c Constant to be printed * @return String representation + * @throws IllegalArgumentException if c is unknown constant type */ - public String constantToString( Constant c ) throws ClassFormatException { + public String constantToString(Constant c) throws IllegalArgumentException { String str; int i; final byte tag = c.getTag(); switch (tag) { - case Const.CONSTANT_Class: - i = ((ConstantClass) c).getNameIndex(); - c = getConstant(i, Const.CONSTANT_Utf8); - str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); - break; - case Const.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - c = getConstant(i, Const.CONSTANT_Utf8); - str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\""; - break; - case Const.CONSTANT_Utf8: - str = ((ConstantUtf8) c).getBytes(); - break; - case Const.CONSTANT_Double: - str = String.valueOf(((ConstantDouble) c).getBytes()); - break; - case Const.CONSTANT_Float: - str = String.valueOf(((ConstantFloat) c).getBytes()); - break; - case Const.CONSTANT_Long: - str = String.valueOf(((ConstantLong) c).getBytes()); - break; - case Const.CONSTANT_Integer: - str = String.valueOf(((ConstantInteger) c).getBytes()); - break; - case Const.CONSTANT_NameAndType: - str = constantToString(((ConstantNameAndType) c).getNameIndex(), - Const.CONSTANT_Utf8) - + " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(), - Const.CONSTANT_Utf8); - break; - case Const.CONSTANT_InterfaceMethodref: - case Const.CONSTANT_Methodref: - case Const.CONSTANT_Fieldref: - str = constantToString(((ConstantCP) c).getClassIndex(), Const.CONSTANT_Class) - + "." + constantToString(((ConstantCP) c).getNameAndTypeIndex(), - Const.CONSTANT_NameAndType); - break; - case Const.CONSTANT_MethodHandle: - // Note that the ReferenceIndex may point to a Fieldref, Methodref or - // InterfaceMethodref - so we need to peek ahead to get the actual type. - final ConstantMethodHandle cmh = (ConstantMethodHandle) c; - str = Const.getMethodHandleName(cmh.getReferenceKind()) - + " " + constantToString(cmh.getReferenceIndex(), - getConstant(cmh.getReferenceIndex()).getTag()); - break; - case Const.CONSTANT_MethodType: - final ConstantMethodType cmt = (ConstantMethodType) c; - str = constantToString(cmt.getDescriptorIndex(), Const.CONSTANT_Utf8); - break; - case Const.CONSTANT_InvokeDynamic: - final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) c; - str = cid.getBootstrapMethodAttrIndex() - + ":" + constantToString(cid.getNameAndTypeIndex(), - Const.CONSTANT_NameAndType); - break; - case Const.CONSTANT_Module: - i = ((ConstantModule) c).getNameIndex(); - c = getConstant(i, Const.CONSTANT_Utf8); - str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); - break; - case Const.CONSTANT_Package: - i = ((ConstantPackage) c).getNameIndex(); - c = getConstant(i, Const.CONSTANT_Utf8); - str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); - break; - default: // Never reached - throw new IllegalArgumentException("Unknown constant type " + tag); + case Const.CONSTANT_Class: + i = ((ConstantClass) c).getNameIndex(); + c = getConstantUtf8(i); + str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); + break; + case Const.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = getConstantUtf8(i); + str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\""; + break; + case Const.CONSTANT_Utf8: + str = ((ConstantUtf8) c).getBytes(); + break; + case Const.CONSTANT_Double: + str = String.valueOf(((ConstantDouble) c).getBytes()); + break; + case Const.CONSTANT_Float: + str = String.valueOf(((ConstantFloat) c).getBytes()); + break; + case Const.CONSTANT_Long: + str = String.valueOf(((ConstantLong) c).getBytes()); + break; + case Const.CONSTANT_Integer: + str = String.valueOf(((ConstantInteger) c).getBytes()); + break; + case Const.CONSTANT_NameAndType: + str = constantToString(((ConstantNameAndType) c).getNameIndex(), Const.CONSTANT_Utf8) + " " + + constantToString(((ConstantNameAndType) c).getSignatureIndex(), Const.CONSTANT_Utf8); + break; + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + case Const.CONSTANT_Fieldref: + str = constantToString(((ConstantCP) c).getClassIndex(), Const.CONSTANT_Class) + "." + + constantToString(((ConstantCP) c).getNameAndTypeIndex(), Const.CONSTANT_NameAndType); + break; + case Const.CONSTANT_MethodHandle: + // Note that the ReferenceIndex may point to a Fieldref, Methodref or + // InterfaceMethodref - so we need to peek ahead to get the actual type. + final ConstantMethodHandle cmh = (ConstantMethodHandle) c; + str = Const.getMethodHandleName(cmh.getReferenceKind()) + " " + + constantToString(cmh.getReferenceIndex(), getConstant(cmh.getReferenceIndex()).getTag()); + break; + case Const.CONSTANT_MethodType: + final ConstantMethodType cmt = (ConstantMethodType) c; + str = constantToString(cmt.getDescriptorIndex(), Const.CONSTANT_Utf8); + break; + case Const.CONSTANT_InvokeDynamic: + final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) c; + str = cid.getBootstrapMethodAttrIndex() + ":" + constantToString(cid.getNameAndTypeIndex(), Const.CONSTANT_NameAndType); + break; + case Const.CONSTANT_Dynamic: + final ConstantDynamic cd = (ConstantDynamic) c; + str = cd.getBootstrapMethodAttrIndex() + ":" + constantToString(cd.getNameAndTypeIndex(), Const.CONSTANT_NameAndType); + break; + case Const.CONSTANT_Module: + i = ((ConstantModule) c).getNameIndex(); + c = getConstantUtf8(i); + str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); + break; + case Const.CONSTANT_Package: + i = ((ConstantPackage) c).getNameIndex(); + c = getConstantUtf8(i); + str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); + break; + default: // Never reached + throw new IllegalArgumentException("Unknown constant type " + tag); } return str; } - private static String escape( final String str ) { - final int len = str.length(); - final StringBuilder buf = new StringBuilder(len + 5); - final char[] ch = str.toCharArray(); - for (int i = 0; i < len; i++) { - switch (ch[i]) { - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - case '\t': - buf.append("\\t"); - break; - case '\b': - buf.append("\\b"); - break; - case '"': - buf.append("\\\""); - break; - default: - buf.append(ch[i]); - } - } - return buf.toString(); - } - /** - * Retrieves constant at `index' from constant pool and resolve it to - * a string representation. + * Retrieves constant at 'index' from constant pool and resolve it to a string representation. * - * @param index of constant in constant pool - * @param tag expected type + * @param index of constant in constant pool + * @param tag expected type * @return String representation */ - public String constantToString( final int index, final byte tag ) throws ClassFormatException { - final Constant c = getConstant(index, tag); - return constantToString(c); + public String constantToString(final int index, final byte tag) { + return constantToString(getConstant(index, tag)); + } + + /** + * @return deep copy of this constant pool + */ + public ConstantPool copy() { + ConstantPool c = null; + try { + c = (ConstantPool) clone(); + c.constantPool = new Constant[constantPool.length]; + for (int i = 1; i < constantPool.length; i++) { + if (constantPool[i] != null) { + c.constantPool[i] = constantPool[i].copy(); + } + } + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return c; } /** * Dump constant pool to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if problem in writeShort or dump */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { /* * Constants over the size of the constant pool shall not be written out. * This is a redundant measure as the ConstantPoolGen should have already * reported an error back in the situation. - */ - int size = constantPool.length < ConstantPoolGen.CONSTANT_POOL_SIZE ? - constantPool.length : ConstantPoolGen.CONSTANT_POOL_SIZE; + */ + final int size = Math.min(constantPool.length, Const.MAX_CP_ENTRIES); file.writeShort(size); for (int i = 1; i < size; i++) { @@ -242,94 +252,151 @@ /** * Gets constant from constant pool. * - * @param index Index in constant pool + * @param index Index in constant pool * @return Constant value - * @see Constant + * @see Constant + * @throws ClassFormatException if index is invalid */ - public Constant getConstant( final int index ) { - if (index >= constantPool.length || index < 0) { - throw new ClassFormatException("Invalid constant pool reference: " + index - + ". Constant pool size is: " + constantPool.length); + @SuppressWarnings("unchecked") + public T getConstant(final int index) throws ClassFormatException { + return (T) getConstant(index, Constant.class); + } + + /** + * Gets constant from constant pool and check whether it has the expected type. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, i.e., its type + * @return Constant value + * @see Constant + * @throws ClassFormatException if constant type does not match tag + */ + @SuppressWarnings("unchecked") + public T getConstant(final int index, final byte tag) throws ClassFormatException { + return (T) getConstant(index, tag, Constant.class); + } + + /** + * Gets constant from constant pool and check whether it has the expected type. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, i.e., its type + * @return Constant value + * @see Constant + * @throws ClassFormatException if constant type does not match tag + * @since 6.6.0 + */ + public T getConstant(final int index, final byte tag, final Class castTo) throws ClassFormatException { + final T c = getConstant(index); + if (c.getTag() != tag) { + throw new ClassFormatException("Expected class '" + Const.getConstantName(tag) + "' at index " + index + " and got " + c); } - return constantPool[index]; + return c; } /** - * Gets constant from constant pool and check whether it has the - * expected type. + * Gets constant from constant pool. * - * @param index Index in constant pool - * @param tag Tag of expected constant, i.e., its type + * @param A {@link Constant} subclass + * @param index Index in constant pool + * @param castTo The {@link Constant} subclass to cast to. * @return Constant value - * @see Constant - * @throws ClassFormatException + * @see Constant + * @throws ClassFormatException if index is invalid + * @since 6.6.0 */ - public Constant getConstant( final int index, final byte tag ) throws ClassFormatException { - Constant c; - c = getConstant(index); - if (c == null) { - throw new ClassFormatException("Constant pool at index " + index + " is null."); + public T getConstant(final int index, final Class castTo) throws ClassFormatException { + if (index >= constantPool.length || index < 0) { + throw new ClassFormatException("Invalid constant pool reference using index: " + index + ". Constant pool size is: " + constantPool.length); } - if (c.getTag() != tag) { - throw new ClassFormatException("Expected class `" + Const.getConstantName(tag) - + "' at index " + index + " and got " + c); + if (constantPool[index] != null && !castTo.isAssignableFrom(constantPool[index].getClass())) { + throw new ClassFormatException("Invalid constant pool reference at index: " + index + + ". Expected " + castTo + " but was " + constantPool[index].getClass()); + } + // Previous check ensures this won't throw a ClassCastException + final T c = castTo.cast(constantPool[index]); + if (c == null + // the 0th element is always null + && index != 0) { + final Constant prev = constantPool[index - 1]; + if (prev == null || prev.getTag() != Const.CONSTANT_Double && prev.getTag() != Const.CONSTANT_Long) { + throw new ClassFormatException("Constant pool at index " + index + " is null."); + } } return c; } /** + * Gets constant from constant pool and check whether it has the expected type. + * + * @param index Index in constant pool + * @return ConstantInteger value + * @see ConstantInteger + * @throws ClassFormatException if constant type does not match tag + */ + public ConstantInteger getConstantInteger(final int index) { + return getConstant(index, Const.CONSTANT_Integer, ConstantInteger.class); + } + + /** * @return Array of constants. - * @see Constant + * @see Constant */ public Constant[] getConstantPool() { return constantPool; } /** - * Gets string from constant pool and bypass the indirection of - * `ConstantClass' and `ConstantString' objects. I.e. these classes have - * an index field that points to another entry of the constant pool of - * type `ConstantUtf8' which contains the real data. + * Gets string from constant pool and bypass the indirection of 'ConstantClass' and 'ConstantString' objects. I.e. these classes have an index field that + * points to another entry of the constant pool of type 'ConstantUtf8' which contains the real data. * - * @param index Index in constant pool - * @param tag Tag of expected constant, either ConstantClass or ConstantString + * @param index Index in constant pool + * @param tag Tag of expected constant, either ConstantClass or ConstantString * @return Contents of string reference - * @see ConstantClass - * @see ConstantString - * @throws ClassFormatException + * @see ConstantClass + * @see ConstantString + * @throws IllegalArgumentException if tag is invalid */ - public String getConstantString( final int index, final byte tag ) throws ClassFormatException { - Constant c; + public String getConstantString(final int index, final byte tag) throws IllegalArgumentException { int i; - c = getConstant(index, tag); - /* This switch() is not that elegant, since the four classes have the - * same contents, they just differ in the name of the index - * field variable. - * But we want to stick to the JVM naming conventions closely though - * we could have solved these more elegantly by using the same - * variable name or by subclassing. + /* + * This switch() is not that elegant, since the four classes have the same contents, they just differ in the name of the index field variable. But we + * want to stick to the JVM naming conventions closely though we could have solved these more elegantly by using the same variable name or by + * subclassing. */ switch (tag) { - case Const.CONSTANT_Class: - i = ((ConstantClass) c).getNameIndex(); - break; - case Const.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - break; - case Const.CONSTANT_Module: - i = ((ConstantModule) c).getNameIndex(); - break; - case Const.CONSTANT_Package: - i = ((ConstantPackage) c).getNameIndex(); - break; - default: - throw new IllegalArgumentException("getConstantString called with illegal tag " + tag); + case Const.CONSTANT_Class: + i = getConstant(index, ConstantClass.class).getNameIndex(); + break; + case Const.CONSTANT_String: + i = getConstant(index, ConstantString.class).getStringIndex(); + break; + case Const.CONSTANT_Module: + i = getConstant(index, ConstantModule.class).getNameIndex(); + break; + case Const.CONSTANT_Package: + i = getConstant(index, ConstantPackage.class).getNameIndex(); + break; + case Const.CONSTANT_Utf8: + return getConstantUtf8(index).getBytes(); + default: + throw new IllegalArgumentException("getConstantString called with illegal tag " + tag); } // Finally get the string from the constant pool - c = getConstant(i, Const.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); + return getConstantUtf8(i).getBytes(); } + /** + * Gets constant from constant pool and check whether it has the expected type. + * + * @param index Index in constant pool + * @return ConstantUtf8 value + * @see ConstantUtf8 + * @throws ClassFormatException if constant type does not match tag + */ + public ConstantUtf8 getConstantUtf8(final int index) throws ClassFormatException { + return getConstant(index, Const.CONSTANT_Utf8, ConstantUtf8.class); + } /** * @return Length of constant pool. @@ -338,23 +405,25 @@ return constantPool == null ? 0 : constantPool.length; } + @Override + public Iterator iterator() { + return Arrays.stream(constantPool).iterator(); + } /** * @param constant Constant to set */ - public void setConstant( final int index, final Constant constant ) { + public void setConstant(final int index, final Constant constant) { constantPool[index] = constant; } - /** * @param constantPool */ - public void setConstantPool( final Constant[] constantPool ) { + public void setConstantPool(final Constant[] constantPool) { this.constantPool = constantPool; } - /** * @return String representation. */ @@ -366,24 +435,4 @@ } return buf.toString(); } - - - /** - * @return deep copy of this constant pool - */ - public ConstantPool copy() { - ConstantPool c = null; - try { - c = (ConstantPool) clone(); - c.constantPool = new Constant[constantPool.length]; - for (int i = 1; i < constantPool.length; i++) { - if (constantPool[i] != null) { - c.constantPool[i] = constantPool[i].copy(); - } - } - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,35 +28,33 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from the abstract {@link Constant} - * and represents a reference to a String object. + * This class is derived from the abstract {@link Constant} and represents a reference to a String object. * - * @see Constant + * @see Constant */ public final class ConstantString extends Constant implements ConstantObject { private int stringIndex; // Identical to ConstantClass except for this name - /** * Initialize from another object. + * + * @param c Source to copy. */ public ConstantString(final ConstantString c) { this(c.getStringIndex()); } - /** * Initialize instance from file data. * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantString(final DataInput file) throws IOException { this(file.readUnsignedShort()); } - /** * @param stringIndex Index of Constant_Utf8 in constant pool */ @@ -65,32 +63,43 @@ this.stringIndex = stringIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantString(this); } - /** * Dump constant field reference to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(super.getTag()); file.writeShort(stringIndex); } + /** + * @return dereferenced string + */ + public String getBytes(final ConstantPool cp) { + return (String) getConstantValue(cp); + } + + /** + * @return String object + */ + @Override + public Object getConstantValue(final ConstantPool cp) { + return cp.getConstantUtf8(stringIndex).getBytes(); + } /** * @return Index in constant pool of the string (ConstantUtf8). @@ -99,15 +108,13 @@ return stringIndex; } - /** * @param stringIndex the index into the constant of the string value */ - public void setStringIndex( final int stringIndex ) { + public void setStringIndex(final int stringIndex) { this.stringIndex = stringIndex; } - /** * @return String representation. */ @@ -115,20 +122,4 @@ public String toString() { return super.toString() + "(stringIndex = " + stringIndex + ")"; } - - - /** @return String object - */ - @Override - public Object getConstantValue( final ConstantPool cp ) { - final Constant c = cp.getConstant(stringIndex, Const.CONSTANT_Utf8); - return ((ConstantUtf8) c).getBytes(); - } - - - /** @return dereferenced string - */ - public String getBytes( final ConstantPool cp ) { - return (String) getConstantValue(cp); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,19 +20,45 @@ package com.sun.org.apache.bcel.internal.classfile; -import com.sun.org.apache.bcel.internal.Const; import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; + +import com.sun.org.apache.bcel.internal.Const; /** * Extends the abstract {@link Constant} to represent a reference to a UTF-8 encoded string. + *

    + * The following system properties govern caching this class performs. + *

    + *
      + *
    • {@value #SYS_PROP_CACHE_MAX_ENTRIES} (since 6.4): The size of the cache, by default 0, meaning caching is + * disabled.
    • + *
    • {@value #SYS_PROP_CACHE_MAX_ENTRY_SIZE} (since 6.0): The maximum size of the values to cache, by default 200, 0 + * disables caching. Values larger than this are not cached.
    • + *
    • {@value #SYS_PROP_STATISTICS} (since 6.0): Prints statistics on the console when the JVM exits.
    • + *
    + *

    + * Here is a sample Maven invocation with caching disabled: + *

    + * + *
    + * mvn test -Dbcel.statistics=true -Dbcel.maxcached.size=0 -Dbcel.maxcached=0
    + * 
    + *

    + * Here is a sample Maven invocation with caching enabled: + *

    + * + *
    + * mvn test -Dbcel.statistics=true -Dbcel.maxcached.size=100000 -Dbcel.maxcached=5000000
    + * 
    * * @see Constant - * @LastModified: Jan 2020 + * @LastModified: Feb 2023 */ public final class ConstantUtf8 extends Constant { @@ -42,8 +68,7 @@ private static final int MAX_ENTRIES = 20000; private static final int INITIAL_CAPACITY = (int) (MAX_ENTRIES / 0.75); - private static final HashMap CACHE = new LinkedHashMap( - INITIAL_CAPACITY, 0.75f, true) { + private static final HashMap CACHE = new LinkedHashMap(INITIAL_CAPACITY, 0.75f, true) { private static final long serialVersionUID = -8506975356158971766L; @@ -62,6 +87,22 @@ } + // TODO these should perhaps be AtomicInt? + private static volatile int considered; + private static volatile int created; + private static volatile int hits; + private static volatile int skipped; + + private static final String SYS_PROP_CACHE_MAX_ENTRIES = "bcel.maxcached"; + private static final String SYS_PROP_CACHE_MAX_ENTRY_SIZE = "bcel.maxcached.size"; + private static final String SYS_PROP_STATISTICS = "bcel.statistics"; + + static { + if (Cache.BCEL_STATISTICS) { + Runtime.getRuntime().addShutdownHook(new Thread(ConstantUtf8::printStats)); + } + } + /** * Clears the cache. * @@ -71,6 +112,11 @@ Cache.CACHE.clear(); } + // for access by test code + static synchronized void clearStats() { + hits = considered = skipped = created = 0; + } + /** * Gets a new or cached instance of the given value. *

    @@ -83,12 +129,14 @@ */ public static ConstantUtf8 getCachedInstance(final String value) { if (value.length() > Cache.MAX_ENTRY_SIZE) { + skipped++; return new ConstantUtf8(value); } - + considered++; synchronized (ConstantUtf8.class) { // might be better with a specific lock object ConstantUtf8 result = Cache.CACHE.get(value); if (result != null) { + hits++; return result; } result = new ConstantUtf8(value); @@ -126,6 +174,15 @@ return Cache.isEnabled() ? getCachedInstance(value) : new ConstantUtf8(value); } + // for access by test code + static void printStats() { + final String prefix = "[Apache Commons BCEL]"; + System.err.printf("%s Cache hit %,d/%,d, %d skipped.%n", prefix, hits, considered, skipped); + System.err.printf("%s Total of %,d ConstantUtf8 objects created.%n", prefix, created); + System.err.printf("%s Configuration: %s=%,d, %s=%,d.%n", prefix, SYS_PROP_CACHE_MAX_ENTRIES, Cache.MAX_ENTRIES, SYS_PROP_CACHE_MAX_ENTRY_SIZE, + Cache.MAX_ENTRY_SIZE); + } + private final String value; /** @@ -141,11 +198,12 @@ * Initializes instance from file data. * * @param dataInput Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ ConstantUtf8(final DataInput dataInput) throws IOException { super(Const.CONSTANT_Utf8); value = dataInput.readUTF(); + created++; } /** @@ -153,14 +211,12 @@ */ public ConstantUtf8(final String value) { super(Const.CONSTANT_Utf8); - if (value == null) { - throw new IllegalArgumentException("Value must not be null."); - } - this.value = value; + this.value = Objects.requireNonNull(value, "value"); + created++; } /** - * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object @@ -174,7 +230,7 @@ * Dumps String in Utf8 format to file stream. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override public void dump(final DataOutputStream file) throws IOException { diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,81 +26,92 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and represents a constant - * value, i.e., a default value for initializing a class field. - * This class is instantiated by the Attribute.readAttribute() method. + * This class is derived from Attribute and represents a constant value, i.e., a default value for initializing + * a class field. This class is instantiated by the Attribute.readAttribute() method. * - * @see Attribute + *

    + * ConstantValue_attribute {
    + *   u2 attribute_name_index;
    + *   u4 attribute_length;
    + *   u2 constantvalue_index;
    + * }
    + * 
    + * @see Attribute */ public final class ConstantValue extends Attribute { private int constantValueIndex; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. */ public ConstantValue(final ConstantValue c) { this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool()); } - /** * Construct object from input stream. - * @param name_index Name index in constant pool + * + * @param nameIndex Name index in constant pool * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - ConstantValue(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, input.readUnsignedShort(), constant_pool); + ConstantValue(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, input.readUnsignedShort(), constantPool); } - /** - * @param name_index Name index in constant pool + * @param nameIndex Name index in constant pool * @param length Content length in bytes * @param constantValueIndex Index in constant pool - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public ConstantValue(final int name_index, final int length, final int constantValueIndex, - final ConstantPool constant_pool) { - super(Const.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); + public ConstantValue(final int nameIndex, final int length, final int constantValueIndex, final ConstantPool constantPool) { + super(Const.ATTR_CONSTANT_VALUE, nameIndex, Args.require(length, 2, "ConstantValue attribute length"), constantPool); this.constantValueIndex = constantValueIndex; } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitConstantValue(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final ConstantValue c = (ConstantValue) clone(); + c.setConstantPool(constantPool); + return c; + } /** * Dump constant value attribute to file stream on binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(constantValueIndex); } - /** * @return Index in constant pool of constant value. */ @@ -108,15 +119,13 @@ return constantValueIndex; } - /** * @param constantValueIndex the index info the constant pool of this constant value */ - public void setConstantValueIndex( final int constantValueIndex ) { + public void setConstantValueIndex(final int constantValueIndex) { this.constantValueIndex = constantValueIndex; } - /** * @return String representation of constant value. */ @@ -127,37 +136,26 @@ int i; // Print constant to string depending on its type switch (c.getTag()) { - case Const.CONSTANT_Long: - buf = String.valueOf(((ConstantLong) c).getBytes()); - break; - case Const.CONSTANT_Float: - buf = String.valueOf(((ConstantFloat) c).getBytes()); - break; - case Const.CONSTANT_Double: - buf = String.valueOf(((ConstantDouble) c).getBytes()); - break; - case Const.CONSTANT_Integer: - buf = String.valueOf(((ConstantInteger) c).getBytes()); - break; - case Const.CONSTANT_String: - i = ((ConstantString) c).getStringIndex(); - c = super.getConstantPool().getConstant(i, Const.CONSTANT_Utf8); - buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\""; - break; - default: - throw new IllegalStateException("Type of ConstValue invalid: " + c); + case Const.CONSTANT_Long: + buf = String.valueOf(((ConstantLong) c).getBytes()); + break; + case Const.CONSTANT_Float: + buf = String.valueOf(((ConstantFloat) c).getBytes()); + break; + case Const.CONSTANT_Double: + buf = String.valueOf(((ConstantDouble) c).getBytes()); + break; + case Const.CONSTANT_Integer: + buf = String.valueOf(((ConstantInteger) c).getBytes()); + break; + case Const.CONSTANT_String: + i = ((ConstantString) c).getStringIndex(); + c = super.getConstantPool().getConstantUtf8(i); + buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\""; + break; + default: + throw new IllegalStateException("Type of ConstValue invalid: " + c); } return buf; } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final ConstantValue c = (ConstantValue) clone(); - c.setConstantPool(_constant_pool); - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,52 +25,50 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and denotes that this is a - * deprecated method. - * It is instantiated from the Attribute.readAttribute() method. + * This class is derived from Attribute and denotes that this is a deprecated method. It is instantiated from + * the Attribute.readAttribute() method. * - * @see Attribute + * @see Attribute */ public final class Deprecated extends Attribute { private byte[] bytes; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. */ public Deprecated(final Deprecated c) { this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param bytes Attribute contents - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public Deprecated(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { - super(Const.ATTR_DEPRECATED, name_index, length, constant_pool); + public Deprecated(final int nameIndex, final int length, final byte[] bytes, final ConstantPool constantPool) { + super(Const.ATTR_DEPRECATED, nameIndex, Args.require0(length, "Deprecated attribute length"), constantPool); this.bytes = bytes; } - /** * Construct object from input stream. * - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - Deprecated(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, (byte[]) null, constant_pool); + Deprecated(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (byte[]) null, constantPool); if (length > 0) { bytes = new byte[length]; input.readFully(bytes); @@ -78,35 +76,44 @@ } } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitDeprecated(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final Deprecated c = (Deprecated) clone(); + if (bytes != null) { + c.bytes = bytes.clone(); + } + c.setConstantPool(constantPool); + return c; + } /** * Dump source file attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); if (super.getLength() > 0) { file.write(bytes, 0, super.getLength()); } } - /** * @return data bytes. */ @@ -114,35 +121,18 @@ return bytes; } - /** * @param bytes the raw bytes that represents this byte array */ - public void setBytes( final byte[] bytes ) { + public void setBytes(final byte[] bytes) { this.bytes = bytes; } - /** * @return attribute name */ @Override public String toString() { - return Const.getAttributeName(Const.ATTR_DEPRECATED); - } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final Deprecated c = (Deprecated) clone(); - if (bytes != null) { - c.bytes = new byte[bytes.length]; - System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); - } - c.setConstantPool(_constant_pool); - return c; + return Const.getAttributeName(Const.ATTR_DEPRECATED) + ": true"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java 2023-10-06 05:33:33.000000000 +0000 @@ -19,7 +19,9 @@ */ package com.sun.org.apache.bcel.internal.classfile; +import java.util.Objects; import java.util.Stack; +import java.util.stream.Stream; /** * Traverses a JavaClass with another Visitor object 'piggy-backed' that is @@ -27,8 +29,7 @@ * traversal strategy, other classes can make use of it. * */ -public class DescendingVisitor implements Visitor -{ +public class DescendingVisitor implements Visitor { private final JavaClass clazz; private final Visitor visitor; @@ -36,74 +37,59 @@ private final Stack stack = new Stack<>(); /** - * @return container of current entitity, i.e., predecessor during traversal + * @param clazz Class to traverse + * @param visitor visitor object to apply to all components */ - public Object predecessor() - { - return predecessor(0); + public DescendingVisitor(final JavaClass clazz, final Visitor visitor) { + this.clazz = clazz; + this.visitor = visitor; } - /** - * @param level - * nesting level, i.e., 0 returns the direct predecessor - * @return container of current entitity, i.e., predecessor during traversal - */ - public Object predecessor(final int level) - { - final int size = stack.size(); - if ((size < 2) || (level < 0)) - { - return null; - } - return stack.elementAt(size - (level + 2)); // size - 1 == current + private void accept(final E[] node) { + Stream.of(node).forEach(e -> e.accept(this)); } /** * @return current object */ - public Object current() - { + public Object current() { return stack.peek(); } /** - * @param clazz - * Class to traverse - * @param visitor - * visitor object to apply to all components + * @return container of current entitity, i.e., predecessor during traversal */ - public DescendingVisitor(final JavaClass clazz, final Visitor visitor) - { - this.clazz = clazz; - this.visitor = visitor; + public Object predecessor() { + return predecessor(0); + } + + /** + * @param level nesting level, i.e., 0 returns the direct predecessor + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor(final int level) { + final int size = stack.size(); + if (size < 2 || level < 0) { + return null; + } + return stack.elementAt(size - (level + 2)); // size - 1 == current } /** * Start traversal. */ - public void visit() - { + public void visit() { clazz.accept(this); } + /** + * @since 6.0 + */ @Override - public void visitJavaClass(final JavaClass _clazz) - { - stack.push(_clazz); - _clazz.accept(visitor); - final Field[] fields = _clazz.getFields(); - for (final Field field : fields) { - field.accept(this); - } - final Method[] methods = _clazz.getMethods(); - for (final Method method : methods) { - method.accept(this); - } - final Attribute[] attributes = _clazz.getAttributes(); - for (final Attribute attribute : attributes) { - attribute.accept(this); - } - _clazz.getConstantPool().accept(this); + public void visitAnnotation(final Annotations annotation) { + stack.push(annotation); + annotation.accept(visitor); + accept(annotation.getAnnotationEntries()); stack.pop(); } @@ -111,14 +97,9 @@ * @since 6.0 */ @Override - public void visitAnnotation(final Annotations annotation) - { - stack.push(annotation); - annotation.accept(visitor); - final AnnotationEntry[] entries = annotation.getAnnotationEntries(); - for (final AnnotationEntry entrie : entries) { - entrie.accept(this); - } + public void visitAnnotationDefault(final AnnotationDefault obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } @@ -126,327 +107,270 @@ * @since 6.0 */ @Override - public void visitAnnotationEntry(final AnnotationEntry annotationEntry) - { + public void visitAnnotationEntry(final AnnotationEntry annotationEntry) { stack.push(annotationEntry); annotationEntry.accept(visitor); stack.pop(); } + /** + * @since 6.0 + */ @Override - public void visitField(final Field field) - { - stack.push(field); - field.accept(visitor); - final Attribute[] attributes = field.getAttributes(); - for (final Attribute attribute : attributes) { - attribute.accept(this); - } + public void visitBootstrapMethods(final BootstrapMethods bm) { + stack.push(bm); + bm.accept(visitor); + // BootstrapMethod[] bms = bm.getBootstrapMethods(); + // for (int i = 0; i < bms.length; i++) + // { + // bms[i].accept(this); + // } stack.pop(); } @Override - public void visitConstantValue(final ConstantValue cv) - { - stack.push(cv); - cv.accept(visitor); + public void visitCode(final Code code) { + stack.push(code); + code.accept(visitor); + accept(code.getExceptionTable()); + accept(code.getAttributes()); stack.pop(); } @Override - public void visitMethod(final Method method) - { - stack.push(method); - method.accept(visitor); - final Attribute[] attributes = method.getAttributes(); - for (final Attribute attribute : attributes) { - attribute.accept(this); - } + public void visitCodeException(final CodeException ce) { + stack.push(ce); + ce.accept(visitor); stack.pop(); } @Override - public void visitExceptionTable(final ExceptionTable table) - { - stack.push(table); - table.accept(visitor); + public void visitConstantClass(final ConstantClass constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } @Override - public void visitCode(final Code code) - { - stack.push(code); - code.accept(visitor); - final CodeException[] table = code.getExceptionTable(); - for (final CodeException element : table) { - element.accept(this); - } - final Attribute[] attributes = code.getAttributes(); - for (final Attribute attribute : attributes) { - attribute.accept(this); - } + public void visitConstantDouble(final ConstantDouble constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } + /** @since 6.3 */ @Override - public void visitCodeException(final CodeException ce) - { - stack.push(ce); - ce.accept(visitor); + public void visitConstantDynamic(final ConstantDynamic obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } @Override - public void visitLineNumberTable(final LineNumberTable table) - { - stack.push(table); - table.accept(visitor); - final LineNumber[] numbers = table.getLineNumberTable(); - for (final LineNumber number : numbers) { - number.accept(this); - } + public void visitConstantFieldref(final ConstantFieldref constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } @Override - public void visitLineNumber(final LineNumber number) - { - stack.push(number); - number.accept(visitor); + public void visitConstantFloat(final ConstantFloat constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } @Override - public void visitLocalVariableTable(final LocalVariableTable table) - { - stack.push(table); - table.accept(visitor); - final LocalVariable[] vars = table.getLocalVariableTable(); - for (final LocalVariable var : vars) { - var.accept(this); - } + public void visitConstantInteger(final ConstantInteger constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } @Override - public void visitStackMap(final StackMap table) - { - stack.push(table); - table.accept(visitor); - final StackMapEntry[] vars = table.getStackMap(); - for (final StackMapEntry var : vars) { - var.accept(this); - } + public void visitConstantInterfaceMethodref(final ConstantInterfaceMethodref constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } + /** + * @since 6.0 + */ @Override - public void visitStackMapEntry(final StackMapEntry var) - { - stack.push(var); - var.accept(visitor); + public void visitConstantInvokeDynamic(final ConstantInvokeDynamic constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } @Override - public void visitLocalVariable(final LocalVariable var) - { - stack.push(var); - var.accept(visitor); + public void visitConstantLong(final ConstantLong constant) { + stack.push(constant); + constant.accept(visitor); stack.pop(); } + /** @since 6.0 */ @Override - public void visitConstantPool(final ConstantPool cp) - { - stack.push(cp); - cp.accept(visitor); - final Constant[] constants = cp.getConstantPool(); - for (int i = 1; i < constants.length; i++) - { - if (constants[i] != null) - { - constants[i].accept(this); - } - } + public void visitConstantMethodHandle(final ConstantMethodHandle obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } @Override - public void visitConstantClass(final ConstantClass constant) - { + public void visitConstantMethodref(final ConstantMethodref constant) { stack.push(constant); constant.accept(visitor); stack.pop(); } + /** @since 6.0 */ @Override - public void visitConstantDouble(final ConstantDouble constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitConstantMethodType(final ConstantMethodType obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } + /** @since 6.1 */ @Override - public void visitConstantFieldref(final ConstantFieldref constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitConstantModule(final ConstantModule obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } @Override - public void visitConstantFloat(final ConstantFloat constant) - { + public void visitConstantNameAndType(final ConstantNameAndType constant) { stack.push(constant); constant.accept(visitor); stack.pop(); } + /** @since 6.1 */ @Override - public void visitConstantInteger(final ConstantInteger constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitConstantPackage(final ConstantPackage obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } @Override - public void visitConstantInterfaceMethodref( - final ConstantInterfaceMethodref constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitConstantPool(final ConstantPool cp) { + stack.push(cp); + cp.accept(visitor); + Stream.of(cp.getConstantPool()).filter(Objects::nonNull).forEach(e -> e.accept(this)); stack.pop(); } - /** - * @since 6.0 - */ @Override - public void visitConstantInvokeDynamic( - final ConstantInvokeDynamic constant) - { + public void visitConstantString(final ConstantString constant) { stack.push(constant); constant.accept(visitor); stack.pop(); } @Override - public void visitConstantLong(final ConstantLong constant) - { + public void visitConstantUtf8(final ConstantUtf8 constant) { stack.push(constant); constant.accept(visitor); stack.pop(); } @Override - public void visitConstantMethodref(final ConstantMethodref constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitConstantValue(final ConstantValue cv) { + stack.push(cv); + cv.accept(visitor); stack.pop(); } @Override - public void visitConstantNameAndType(final ConstantNameAndType constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitDeprecated(final Deprecated attribute) { + stack.push(attribute); + attribute.accept(visitor); stack.pop(); } + /** + * @since 6.0 + */ @Override - public void visitConstantString(final ConstantString constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitEnclosingMethod(final EnclosingMethod obj) { + stack.push(obj); + obj.accept(visitor); stack.pop(); } @Override - public void visitConstantUtf8(final ConstantUtf8 constant) - { - stack.push(constant); - constant.accept(visitor); + public void visitExceptionTable(final ExceptionTable table) { + stack.push(table); + table.accept(visitor); stack.pop(); } @Override - public void visitInnerClasses(final InnerClasses ic) - { - stack.push(ic); - ic.accept(visitor); - final InnerClass[] ics = ic.getInnerClasses(); - for (final InnerClass ic2 : ics) { - ic2.accept(this); - } + public void visitField(final Field field) { + stack.push(field); + field.accept(visitor); + accept(field.getAttributes()); stack.pop(); } @Override - public void visitInnerClass(final InnerClass inner) - { + public void visitInnerClass(final InnerClass inner) { stack.push(inner); inner.accept(visitor); stack.pop(); } - /** - * @since 6.0 - */ @Override - public void visitBootstrapMethods(final BootstrapMethods bm) - { - stack.push(bm); - bm.accept(visitor); - // BootstrapMethod[] bms = bm.getBootstrapMethods(); - // for (int i = 0; i < bms.length; i++) - // { - // bms[i].accept(this); - // } + public void visitInnerClasses(final InnerClasses ic) { + stack.push(ic); + ic.accept(visitor); + accept(ic.getInnerClasses()); stack.pop(); } @Override - public void visitDeprecated(final Deprecated attribute) - { - stack.push(attribute); - attribute.accept(visitor); + public void visitJavaClass(final JavaClass clazz) { + stack.push(clazz); + clazz.accept(visitor); + accept(clazz.getFields()); + accept(clazz.getMethods()); + accept(clazz.getAttributes()); + clazz.getConstantPool().accept(this); stack.pop(); } @Override - public void visitSignature(final Signature attribute) - { - stack.push(attribute); - attribute.accept(visitor); + public void visitLineNumber(final LineNumber number) { + stack.push(number); + number.accept(visitor); stack.pop(); } @Override - public void visitSourceFile(final SourceFile attribute) - { - stack.push(attribute); - attribute.accept(visitor); + public void visitLineNumberTable(final LineNumberTable table) { + stack.push(table); + table.accept(visitor); + accept(table.getLineNumberTable()); stack.pop(); } @Override - public void visitSynthetic(final Synthetic attribute) - { - stack.push(attribute); - attribute.accept(visitor); + public void visitLocalVariable(final LocalVariable var) { + stack.push(var); + var.accept(visitor); stack.pop(); } @Override - public void visitUnknown(final Unknown attribute) - { - stack.push(attribute); - attribute.accept(visitor); + public void visitLocalVariableTable(final LocalVariableTable table) { + stack.push(table); + table.accept(visitor); + accept(table.getLocalVariableTable()); stack.pop(); } @@ -454,30 +378,25 @@ * @since 6.0 */ @Override - public void visitAnnotationDefault(final AnnotationDefault obj) - { + public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** - * @since 6.0 - */ @Override - public void visitEnclosingMethod(final EnclosingMethod obj) - { - stack.push(obj); - obj.accept(visitor); + public void visitMethod(final Method method) { + stack.push(method); + method.accept(visitor); + accept(method.getAttributes()); stack.pop(); } /** - * @since 6.0 + * @since 6.4.0 */ @Override - public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) - { + public void visitMethodParameter(final MethodParameter obj) { stack.push(obj); obj.accept(visitor); stack.pop(); @@ -487,82 +406,76 @@ * @since 6.0 */ @Override - public void visitParameterAnnotation(final ParameterAnnotations obj) - { + public void visitMethodParameters(final MethodParameters obj) { stack.push(obj); obj.accept(visitor); + Stream.of(obj.getParameters()).forEach(e -> e.accept(this)); stack.pop(); } - /** - * @since 6.0 - */ + /** @since 6.4.0 */ @Override - public void visitMethodParameters(final MethodParameters obj) - { + public void visitModule(final Module obj) { stack.push(obj); obj.accept(visitor); - final MethodParameter[] table = obj.getParameters(); - for (final MethodParameter element : table) { - element.accept(this); - } + accept(obj.getRequiresTable()); + accept(obj.getExportsTable()); + accept(obj.getOpensTable()); + accept(obj.getProvidesTable()); stack.pop(); } - /** - * @since 6.4.0 - */ + /** @since 6.4.0 */ @Override - public void visitMethodParameter(final MethodParameter obj) - { + public void visitModuleExports(final ModuleExports obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.0 */ + /** @since 6.4.0 */ @Override - public void visitConstantMethodType(final ConstantMethodType obj) { + public void visitModuleMainClass(final ModuleMainClass obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.0 */ + /** @since 6.4.0 */ @Override - public void visitConstantMethodHandle(final ConstantMethodHandle obj) { + public void visitModuleOpens(final ModuleOpens obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.0 */ + /** @since 6.4.0 */ @Override - public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) { + public void visitModulePackages(final ModulePackages obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.1 */ + /** @since 6.4.0 */ @Override - public void visitConstantPackage(final ConstantPackage obj) { + public void visitModuleProvides(final ModuleProvides obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.1 */ + /** @since 6.4.0 */ @Override - public void visitConstantModule(final ConstantModule obj) { + public void visitModuleRequires(final ModuleRequires obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.3 */ + /** @since 6.4.0 */ @Override - public void visitConstantDynamic(final ConstantDynamic obj) { + public void visitNestHost(final NestHost obj) { stack.push(obj); obj.accept(visitor); stack.pop(); @@ -570,89 +483,70 @@ /** @since 6.4.0 */ @Override - public void visitModule(final Module obj) { + public void visitNestMembers(final NestMembers obj) { stack.push(obj); obj.accept(visitor); - final ModuleRequires[] rtable = obj.getRequiresTable(); - for (final ModuleRequires element : rtable) { - element.accept(this); - } - final ModuleExports[] etable = obj.getExportsTable(); - for (final ModuleExports element : etable) { - element.accept(this); - } - final ModuleOpens[] otable = obj.getOpensTable(); - for (final ModuleOpens element : otable) { - element.accept(this); - } - final ModuleProvides[] ptable = obj.getProvidesTable(); - for (final ModuleProvides element : ptable) { - element.accept(this); - } stack.pop(); } - /** @since 6.4.0 */ + /** + * @since 6.0 + */ @Override - public void visitModuleRequires(final ModuleRequires obj) { + public void visitParameterAnnotation(final ParameterAnnotations obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.4.0 */ + /** @since 6.0 */ @Override - public void visitModuleExports(final ModuleExports obj) { + public void visitParameterAnnotationEntry(final ParameterAnnotationEntry obj) { stack.push(obj); obj.accept(visitor); stack.pop(); } - /** @since 6.4.0 */ @Override - public void visitModuleOpens(final ModuleOpens obj) { - stack.push(obj); - obj.accept(visitor); + public void visitSignature(final Signature attribute) { + stack.push(attribute); + attribute.accept(visitor); stack.pop(); } - /** @since 6.4.0 */ @Override - public void visitModuleProvides(final ModuleProvides obj) { - stack.push(obj); - obj.accept(visitor); + public void visitSourceFile(final SourceFile attribute) { + stack.push(attribute); + attribute.accept(visitor); stack.pop(); } - /** @since 6.4.0 */ @Override - public void visitModulePackages(final ModulePackages obj) { - stack.push(obj); - obj.accept(visitor); + public void visitStackMap(final StackMap table) { + stack.push(table); + table.accept(visitor); + accept(table.getStackMap()); stack.pop(); } - /** @since 6.4.0 */ @Override - public void visitModuleMainClass(final ModuleMainClass obj) { - stack.push(obj); - obj.accept(visitor); + public void visitStackMapEntry(final StackMapEntry var) { + stack.push(var); + var.accept(visitor); stack.pop(); } - /** @since 6.4.0 */ @Override - public void visitNestHost(final NestHost obj) { - stack.push(obj); - obj.accept(visitor); + public void visitSynthetic(final Synthetic attribute) { + stack.push(attribute); + attribute.accept(visitor); stack.pop(); } - /** @since 6.4.0 */ @Override - public void visitNestMembers(final NestMembers obj) { - stack.push(obj); - obj.accept(visitor); + public void visitUnknown(final Unknown attribute) { + stack.push(attribute); + attribute.accept(visitor); stack.pop(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValue.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,103 +24,155 @@ import java.io.DataOutputStream; import java.io.IOException; +import com.sun.org.apache.bcel.internal.Const; + /** + * The element_value structure is documented at https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.16.1 + * + *
    + * element_value {
    + *    u1 tag;
    + *    union {
    + *        u2 const_value_index;
    + *
    + *        {   u2 type_name_index;
    + *            u2 const_name_index;
    + *        } enum_const_value;
    + *
    + *        u2 class_info_index;
    + *
    + *        annotation annotation_value;
    + *
    + *        {   u2            num_values;
    + *            element_value values[num_values];
    + *        } array_value;
    + *    } value;
    + *}
    + *
    * @since 6.0 * @LastModified: May 2021 */ -public abstract class ElementValue -{ - private final int type; +public abstract class ElementValue { - private final ConstantPool cpool; + public static final byte STRING = 's'; + public static final byte ENUM_CONSTANT = 'e'; + public static final byte CLASS = 'c'; + public static final byte ANNOTATION = '@'; + public static final byte ARRAY = '['; + public static final byte PRIMITIVE_INT = 'I'; + public static final byte PRIMITIVE_BYTE = 'B'; + public static final byte PRIMITIVE_CHAR = 'C'; + public static final byte PRIMITIVE_DOUBLE = 'D'; + public static final byte PRIMITIVE_FLOAT = 'F'; + public static final byte PRIMITIVE_LONG = 'J'; + public static final byte PRIMITIVE_SHORT = 'S'; + public static final byte PRIMITIVE_BOOLEAN = 'Z'; - @Override - public String toString() - { - return stringifyValue(); + /** + * Reads an {@code element_value} as an {@code ElementValue}. + * + * @param input Raw data input. + * @param cpool Constant pool. + * @return a new ElementValue. + * @throws IOException if an I/O error occurs. + */ + public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException { + return readElementValue(input, cpool, 0); + } + + /** + * Reads an {@code element_value} as an {@code ElementValue}. + * + * @param input Raw data input. + * @param cpool Constant pool. + * @param arrayNesting level of current array nesting. + * @return a new ElementValue. + * @throws IOException if an I/O error occurs. + * @since 6.7.0 + */ + public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool, int arrayNesting) + throws IOException { + final byte tag = input.readByte(); + switch (tag) { + case PRIMITIVE_BYTE: + case PRIMITIVE_CHAR: + case PRIMITIVE_DOUBLE: + case PRIMITIVE_FLOAT: + case PRIMITIVE_INT: + case PRIMITIVE_LONG: + case PRIMITIVE_SHORT: + case PRIMITIVE_BOOLEAN: + case STRING: + return new SimpleElementValue(tag, input.readUnsignedShort(), cpool); + + case ENUM_CONSTANT: + return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), input.readUnsignedShort(), cpool); + + case CLASS: + return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool); + + case ANNOTATION: + // TODO isRuntimeVisible + return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(input, cpool, false), cpool); + + case ARRAY: + arrayNesting++; + if (arrayNesting > Const.MAX_ARRAY_DIMENSIONS) { + // JVM spec 4.4.1 + throw new ClassFormatException(String.format("Arrays are only valid if they represent %,d or fewer dimensions.", Const.MAX_ARRAY_DIMENSIONS)); + } + final int numArrayVals = input.readUnsignedShort(); + final ElementValue[] evalues = new ElementValue[numArrayVals]; + for (int j = 0; j < numArrayVals; j++) { + evalues[j] = ElementValue.readElementValue(input, cpool, arrayNesting); + } + return new ArrayElementValue(ARRAY, evalues, cpool); + + default: + throw new ClassFormatException("Unexpected element value tag in annotation: " + tag); + } } - protected ElementValue(final int type, final ConstantPool cpool) - { + /** + * @deprecated (since 6.0) will be made private and final; do not access directly, use getter + */ + @java.lang.Deprecated + protected int type; // TODO should be final + /** + * @deprecated (since 6.0) will be made private and final; do not access directly, use getter + */ + @java.lang.Deprecated + protected ConstantPool cpool; // TODO should be final + + protected ElementValue(final int type, final ConstantPool cpool) { this.type = type; this.cpool = cpool; } - public int getElementValueType() - { - return type; - } - - public abstract String stringifyValue(); - public abstract void dump(DataOutputStream dos) throws IOException; - public static final byte STRING = 's'; - public static final byte ENUM_CONSTANT = 'e'; - public static final byte CLASS = 'c'; - public static final byte ANNOTATION = '@'; - public static final byte ARRAY = '['; - public static final byte PRIMITIVE_INT = 'I'; - public static final byte PRIMITIVE_BYTE = 'B'; - public static final byte PRIMITIVE_CHAR = 'C'; - public static final byte PRIMITIVE_DOUBLE = 'D'; - public static final byte PRIMITIVE_FLOAT = 'F'; - public static final byte PRIMITIVE_LONG = 'J'; - public static final byte PRIMITIVE_SHORT = 'S'; - public static final byte PRIMITIVE_BOOLEAN = 'Z'; - - public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException - { - final byte type = input.readByte(); - switch (type) - { - case PRIMITIVE_BYTE: - case PRIMITIVE_CHAR: - case PRIMITIVE_DOUBLE: - case PRIMITIVE_FLOAT: - case PRIMITIVE_INT: - case PRIMITIVE_LONG: - case PRIMITIVE_SHORT: - case PRIMITIVE_BOOLEAN: - case STRING: - return new SimpleElementValue(type, input.readUnsignedShort(), cpool); - - case ENUM_CONSTANT: - return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), input.readUnsignedShort(), cpool); - - case CLASS: - return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool); - - case ANNOTATION: - // TODO isRuntimeVisible - return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(input, cpool, false), cpool); - - case ARRAY: - final int numArrayVals = input.readUnsignedShort(); - final ElementValue[] evalues = new ElementValue[numArrayVals]; - for (int j = 0; j < numArrayVals; j++) - { - evalues[j] = ElementValue.readElementValue(input, cpool); - } - return new ArrayElementValue(ARRAY, evalues, cpool); - - default: - throw new IllegalArgumentException("Unexpected element value kind in annotation: " + type); - } - } - /** @since 6.0 */ final ConstantPool getConstantPool() { return cpool; } + public int getElementValueType() { + return type; + } + /** @since 6.0 */ final int getType() { return type; } - public String toShortString() - { + public abstract String stringifyValue(); + + public String toShortString() { + return stringifyValue(); + } + + @Override + public String toString() { return stringifyValue(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ElementValuePair.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,56 +24,47 @@ import java.io.DataOutputStream; import java.io.IOException; -import com.sun.org.apache.bcel.internal.Const; - /** - * an annotation's element value pair + * An annotation's element value pair. * * @since 6.0 */ -public class ElementValuePair -{ +public class ElementValuePair { + + static final ElementValuePair[] EMPTY_ARRAY = {}; + private final ElementValue elementValue; private final ConstantPool constantPool; private final int elementNameIndex; - public ElementValuePair(final int elementNameIndex, final ElementValue elementValue, - final ConstantPool constantPool) - { + public ElementValuePair(final int elementNameIndex, final ElementValue elementValue, final ConstantPool constantPool) { this.elementValue = elementValue; this.elementNameIndex = elementNameIndex; this.constantPool = constantPool; } - public String getNameString() - { - final ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant( - elementNameIndex, Const.CONSTANT_Utf8); - return c.getBytes(); + protected void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(elementNameIndex); // u2 name of the element + elementValue.dump(dos); } - public final ElementValue getValue() - { - return elementValue; + public int getNameIndex() { + return elementNameIndex; } - public int getNameIndex() - { - return elementNameIndex; + public String getNameString() { + return constantPool.getConstantUtf8(elementNameIndex).getBytes(); } - public String toShortString() - { - final StringBuilder result = new StringBuilder(); - result.append(getNameString()).append("=").append( - getValue().toShortString()); - return result.toString(); + public final ElementValue getValue() { + return elementValue; } - protected void dump(final DataOutputStream dos) throws IOException { - dos.writeShort(elementNameIndex); // u2 name of the element - elementValue.dump(dos); + public String toShortString() { + final StringBuilder result = new StringBuilder(); + result.append(getNameString()).append("=").append(getValue().toShortString()); + return result.toString(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,355 +22,304 @@ package com.sun.org.apache.bcel.internal.classfile; /** - * Visitor with empty method bodies, can be extended and used in conjunction - * with the DescendingVisitor class, e.g. By courtesy of David Spencer. + * Visitor with empty method bodies, can be extended and used in conjunction with the DescendingVisitor class, e.g. By + * courtesy of David Spencer. * * @see DescendingVisitor */ -public class EmptyVisitor implements Visitor -{ - protected EmptyVisitor() - { +public class EmptyVisitor implements Visitor { + protected EmptyVisitor() { } /** * @since 6.0 */ @Override - public void visitAnnotation(final Annotations obj) - { + public void visitAnnotation(final Annotations obj) { } /** * @since 6.0 */ @Override - public void visitParameterAnnotation(final ParameterAnnotations obj) - { + public void visitAnnotationDefault(final AnnotationDefault obj) { } /** * @since 6.0 */ @Override - public void visitAnnotationEntry(final AnnotationEntry obj) - { + public void visitAnnotationEntry(final AnnotationEntry obj) { } /** * @since 6.0 */ @Override - public void visitAnnotationDefault(final AnnotationDefault obj) - { + public void visitBootstrapMethods(final BootstrapMethods obj) { } @Override - public void visitCode(final Code obj) - { + public void visitCode(final Code obj) { } @Override - public void visitCodeException(final CodeException obj) - { + public void visitCodeException(final CodeException obj) { } @Override - public void visitConstantClass(final ConstantClass obj) - { + public void visitConstantClass(final ConstantClass obj) { } @Override - public void visitConstantDouble(final ConstantDouble obj) - { + public void visitConstantDouble(final ConstantDouble obj) { } + /** + * @since 6.3 + */ @Override - public void visitConstantFieldref(final ConstantFieldref obj) - { + public void visitConstantDynamic(final ConstantDynamic obj) { } @Override - public void visitConstantFloat(final ConstantFloat obj) - { + public void visitConstantFieldref(final ConstantFieldref obj) { } @Override - public void visitConstantInteger(final ConstantInteger obj) - { + public void visitConstantFloat(final ConstantFloat obj) { } @Override - public void visitConstantInterfaceMethodref(final ConstantInterfaceMethodref obj) - { + public void visitConstantInteger(final ConstantInteger obj) { } @Override - public void visitConstantInvokeDynamic(final ConstantInvokeDynamic obj) - { + public void visitConstantInterfaceMethodref(final ConstantInterfaceMethodref obj) { } @Override - public void visitConstantLong(final ConstantLong obj) - { + public void visitConstantInvokeDynamic(final ConstantInvokeDynamic obj) { } @Override - public void visitConstantMethodref(final ConstantMethodref obj) - { + public void visitConstantLong(final ConstantLong obj) { } + /** + * @since 6.0 + */ @Override - public void visitConstantNameAndType(final ConstantNameAndType obj) - { + public void visitConstantMethodHandle(final ConstantMethodHandle constantMethodHandle) { + } + + @Override + public void visitConstantMethodref(final ConstantMethodref obj) { } + /** + * @since 6.0 + */ @Override - public void visitConstantPool(final ConstantPool obj) - { + public void visitConstantMethodType(final ConstantMethodType obj) { } + /** + * @since 6.1 + */ @Override - public void visitConstantString(final ConstantString obj) - { + public void visitConstantModule(final ConstantModule constantModule) { } @Override - public void visitConstantUtf8(final ConstantUtf8 obj) - { + public void visitConstantNameAndType(final ConstantNameAndType obj) { } + /** + * @since 6.1 + */ @Override - public void visitConstantValue(final ConstantValue obj) - { + public void visitConstantPackage(final ConstantPackage constantPackage) { } @Override - public void visitDeprecated(final Deprecated obj) - { + public void visitConstantPool(final ConstantPool obj) { } @Override - public void visitExceptionTable(final ExceptionTable obj) - { + public void visitConstantString(final ConstantString obj) { } @Override - public void visitField(final Field obj) - { + public void visitConstantUtf8(final ConstantUtf8 obj) { } @Override - public void visitInnerClass(final InnerClass obj) - { + public void visitConstantValue(final ConstantValue obj) { } @Override - public void visitInnerClasses(final InnerClasses obj) - { + public void visitDeprecated(final Deprecated obj) { } /** * @since 6.0 */ @Override - public void visitBootstrapMethods(final BootstrapMethods obj) - { - } - - @Override - public void visitJavaClass(final JavaClass obj) - { + public void visitEnclosingMethod(final EnclosingMethod obj) { } @Override - public void visitLineNumber(final LineNumber obj) - { + public void visitExceptionTable(final ExceptionTable obj) { } @Override - public void visitLineNumberTable(final LineNumberTable obj) - { + public void visitField(final Field obj) { } @Override - public void visitLocalVariable(final LocalVariable obj) - { + public void visitInnerClass(final InnerClass obj) { } @Override - public void visitLocalVariableTable(final LocalVariableTable obj) - { + public void visitInnerClasses(final InnerClasses obj) { } @Override - public void visitMethod(final Method obj) - { + public void visitJavaClass(final JavaClass obj) { } @Override - public void visitSignature(final Signature obj) - { + public void visitLineNumber(final LineNumber obj) { } @Override - public void visitSourceFile(final SourceFile obj) - { + public void visitLineNumberTable(final LineNumberTable obj) { } @Override - public void visitSynthetic(final Synthetic obj) - { + public void visitLocalVariable(final LocalVariable obj) { } @Override - public void visitUnknown(final Unknown obj) - { + public void visitLocalVariableTable(final LocalVariableTable obj) { } + /** + * @since 6.0 + */ @Override - public void visitStackMap(final StackMap obj) - { + public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) { } @Override - public void visitStackMapEntry(final StackMapEntry obj) - { + public void visitMethod(final Method obj) { } /** * @since 6.0 - @Override - public void visitStackMapTable(StackMapTable obj) - { - } + * @Override public void visitStackMapTable(StackMapTable obj) { } */ /** * @since 6.0 - @Override - public void visitStackMapTableEntry(StackMapTableEntry obj) - { - } + * @Override public void visitStackMapTableEntry(StackMapTableEntry obj) { } */ /** - * @since 6.0 + * @since 6.4.0 */ @Override - public void visitEnclosingMethod(final EnclosingMethod obj) - { + public void visitMethodParameter(final MethodParameter obj) { } /** * @since 6.0 */ @Override - public void visitLocalVariableTypeTable(final LocalVariableTypeTable obj) - { + public void visitMethodParameters(final MethodParameters obj) { } - /** - * @since 6.0 - */ + /** @since 6.4.0 */ @Override - public void visitMethodParameters(final MethodParameters obj) - { + public void visitModule(final Module obj) { } - /** - * @since 6.4.0 - */ + /** @since 6.4.0 */ @Override - public void visitMethodParameter(final MethodParameter obj) - { + public void visitModuleExports(final ModuleExports obj) { } - /** - * @since 6.0 - */ + /** @since 6.4.0 */ @Override - public void visitConstantMethodType(final ConstantMethodType obj) - { + public void visitModuleMainClass(final ModuleMainClass obj) { } - /** - * @since 6.0 - */ + /** @since 6.4.0 */ @Override - public void visitConstantMethodHandle(final ConstantMethodHandle constantMethodHandle) { + public void visitModuleOpens(final ModuleOpens obj) { } - /** - * @since 6.0 - */ + /** @since 6.4.0 */ @Override - public void visitParameterAnnotationEntry(final ParameterAnnotationEntry parameterAnnotationEntry) { + public void visitModulePackages(final ModulePackages obj) { } - /** - * @since 6.1 - */ + /** @since 6.4.0 */ @Override - public void visitConstantPackage(final ConstantPackage constantPackage) { + public void visitModuleProvides(final ModuleProvides obj) { } - /** - * @since 6.1 - */ + /** @since 6.4.0 */ @Override - public void visitConstantModule(final ConstantModule constantModule) { + public void visitModuleRequires(final ModuleRequires obj) { } - /** - * @since 6.3 - */ + /** @since 6.4.0 */ @Override - public void visitConstantDynamic(final ConstantDynamic obj) { + public void visitNestHost(final NestHost obj) { } /** @since 6.4.0 */ @Override - public void visitModule(final Module obj) { + public void visitNestMembers(final NestMembers obj) { } - /** @since 6.4.0 */ + /** + * @since 6.0 + */ @Override - public void visitModuleRequires(final ModuleRequires obj) { + public void visitParameterAnnotation(final ParameterAnnotations obj) { } - /** @since 6.4.0 */ + /** + * @since 6.0 + */ @Override - public void visitModuleExports(final ModuleExports obj) { + public void visitParameterAnnotationEntry(final ParameterAnnotationEntry parameterAnnotationEntry) { } - /** @since 6.4.0 */ @Override - public void visitModuleOpens(final ModuleOpens obj) { + public void visitSignature(final Signature obj) { } - /** @since 6.4.0 */ @Override - public void visitModuleProvides(final ModuleProvides obj) { + public void visitSourceFile(final SourceFile obj) { } - /** @since 6.4.0 */ @Override - public void visitModulePackages(final ModulePackages obj) { + public void visitStackMap(final StackMap obj) { } - /** @since 6.4.0 */ @Override - public void visitModuleMainClass(final ModuleMainClass obj) { + public void visitStackMapEntry(final StackMapEntry obj) { } - /** @since 6.4.0 */ @Override - public void visitNestHost(final NestHost obj) { + public void visitSynthetic(final Synthetic obj) { } - /** @since 6.4.0 */ @Override - public void visitNestMembers(final NestMembers obj) { + public void visitUnknown(final Unknown obj) { } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnclosingMethod.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,10 +26,10 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This attribute exists for local or - * anonymous classes and ... there can be only one. + * This attribute exists for local or anonymous classes and ... there can be only one. * * @since 6.0 */ @@ -41,10 +41,10 @@ // If the current class is not immediately enclosed by a method or // constructor, then the value of the method_index item must be zero. - // Otherwise, the value of the method_index item must point to a + // Otherwise, the value of the method_index item must point to a // CONSTANT_NameAndType_info structure representing the name and the // type of a method in the class referenced by the class we point - // to in the class_index. *It is the compiler responsibility* to + // to in the class_index. *It is the compiler responsibility* to // ensure that the method identified by this index is the closest // lexically enclosing method that includes the local/anonymous class. private int methodIndex; @@ -54,27 +54,45 @@ this(nameIndex, len, input.readUnsignedShort(), input.readUnsignedShort(), cpool); } - private EnclosingMethod(final int nameIndex, final int len, final int classIdx,final int methodIdx, final ConstantPool cpool) { - super(Const.ATTR_ENCLOSING_METHOD, nameIndex, len, cpool); - classIndex = classIdx; - methodIndex = methodIdx; + private EnclosingMethod(final int nameIndex, final int len, final int classIndex, final int methodIndex, final ConstantPool cpool) { + super(Const.ATTR_ENCLOSING_METHOD, nameIndex, Args.require(len, 4, "EnclosingMethod attribute length"), cpool); + this.classIndex = Args.requireU2(classIndex, 0, cpool.getLength(), "EnclosingMethod class index"); + this.methodIndex = Args.requireU2(methodIndex, "EnclosingMethod method index"); } @Override public void accept(final Visitor v) { - v.visitEnclosingMethod(this); + v.visitEnclosingMethod(this); } @Override - public Attribute copy(final ConstantPool constant_pool) { + public Attribute copy(final ConstantPool constantPool) { return (Attribute) clone(); } + @Override + public final void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(classIndex); + file.writeShort(methodIndex); + } + + public final ConstantClass getEnclosingClass() { + return super.getConstantPool().getConstant(classIndex, Const.CONSTANT_Class, ConstantClass.class); + } + // Accessors public final int getEnclosingClassIndex() { return classIndex; } + public final ConstantNameAndType getEnclosingMethod() { + if (methodIndex == 0) { + return null; + } + return super.getConstantPool().getConstant(methodIndex, Const.CONSTANT_NameAndType, ConstantNameAndType.class); + } + public final int getEnclosingMethodIndex() { return methodIndex; } @@ -86,26 +104,4 @@ public final void setEnclosingMethodIndex(final int idx) { methodIndex = idx; } - - public final ConstantClass getEnclosingClass() { - final ConstantClass c = - (ConstantClass)super.getConstantPool().getConstant(classIndex,Const.CONSTANT_Class); - return c; - } - - public final ConstantNameAndType getEnclosingMethod() { - if (methodIndex == 0) { - return null; - } - final ConstantNameAndType nat = - (ConstantNameAndType)super.getConstantPool().getConstant(methodIndex,Const.CONSTANT_NameAndType); - return nat; - } - - @Override - public final void dump(final DataOutputStream file) throws IOException { - super.dump(file); - file.writeShort(classIndex); - file.writeShort(methodIndex); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/EnumElementValue.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,67 +24,49 @@ import java.io.DataOutputStream; import java.io.IOException; -import com.sun.org.apache.bcel.internal.Const; - /** * @since 6.0 */ -public class EnumElementValue extends ElementValue -{ +public class EnumElementValue extends ElementValue { // For enum types, these two indices point to the type and value private final int typeIdx; private final int valueIdx; - public EnumElementValue(final int type, final int typeIdx, final int valueIdx, - final ConstantPool cpool) - { + public EnumElementValue(final int type, final int typeIdx, final int valueIdx, final ConstantPool cpool) { super(type, cpool); if (type != ENUM_CONSTANT) { - throw new IllegalArgumentException( - "Only element values of type enum can be built with this ctor - type specified: " + type); + throw new ClassFormatException("Only element values of type enum can be built with this ctor - type specified: " + type); } this.typeIdx = typeIdx; this.valueIdx = valueIdx; } @Override - public void dump(final DataOutputStream dos) throws IOException - { + public void dump(final DataOutputStream dos) throws IOException { dos.writeByte(super.getType()); // u1 type of value (ENUM_CONSTANT == 'e') dos.writeShort(typeIdx); // u2 dos.writeShort(valueIdx); // u2 } - @Override - public String stringifyValue() - { - final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(valueIdx, - Const.CONSTANT_Utf8); - return cu8.getBytes(); + public String getEnumTypeString() { + return super.getConstantPool().getConstantUtf8(typeIdx).getBytes(); } - public String getEnumTypeString() - { - final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(typeIdx, - Const.CONSTANT_Utf8); - return cu8.getBytes();// Utility.signatureToString(cu8.getBytes()); + public String getEnumValueString() { + return super.getConstantPool().getConstantUtf8(valueIdx).getBytes(); } - public String getEnumValueString() - { - final ConstantUtf8 cu8 = (ConstantUtf8) super.getConstantPool().getConstant(valueIdx, - Const.CONSTANT_Utf8); - return cu8.getBytes(); + public int getTypeIndex() { + return typeIdx; } - public int getValueIndex() - { + public int getValueIndex() { return valueIdx; } - public int getTypeIndex() - { - return typeIdx; + @Override + public String stringifyValue() { + return super.getConstantPool().getConstantUtf8(valueIdx).getBytes(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,85 +23,104 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class represents the table of exceptions that are thrown by a - * method. This attribute may be used once per method. The name of - * this class is ExceptionTable for historical reasons; The - * Java Virtual Machine Specification, Second Edition defines this - * attribute using the name Exceptions (which is inconsistent - * with the other classes). + * This class represents the table of exceptions that are thrown by a method. This attribute may be used once per + * method. The name of this class is ExceptionTable for historical reasons; The Java Virtual Machine + * Specification, Second Edition defines this attribute using the name Exceptions (which is inconsistent with + * the other classes). * - * @see Code + *
    + * Exceptions_attribute {
    + *   u2 attribute_name_index;
    + *   u4 attribute_length;
    + *   u2 number_of_exceptions;
    + *   u2 exception_index_table[number_of_exceptions];
    + * }
    + * 
    + * @see Code + * @LastModified: Feb 2023 */ public final class ExceptionTable extends Attribute { private int[] exceptionIndexTable; // constant pool - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. */ public ExceptionTable(final ExceptionTable c) { this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool()); } - - /** - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param exceptionIndexTable Table of indices in constant pool - * @param constant_pool Array of constants - */ - public ExceptionTable(final int name_index, final int length, final int[] exceptionIndexTable, - final ConstantPool constant_pool) { - super(Const.ATTR_EXCEPTIONS, name_index, length, constant_pool); - this.exceptionIndexTable = exceptionIndexTable != null ? exceptionIndexTable : new int[0]; - } - - /** * Construct object from input stream. + * * @param nameIndex Index in constant pool * @param length Content length in bytes * @param input Input stream * @param constantPool Array of constants - * @throws IOException + * @throws IOException if an I/O error occurs. */ ExceptionTable(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { this(nameIndex, length, (int[]) null, constantPool); - final int number_of_exceptions = input.readUnsignedShort(); - exceptionIndexTable = new int[number_of_exceptions]; - for (int i = 0; i < number_of_exceptions; i++) { + final int exceptionCount = input.readUnsignedShort(); + exceptionIndexTable = new int[exceptionCount]; + for (int i = 0; i < exceptionCount; i++) { exceptionIndexTable[i] = input.readUnsignedShort(); } } + /** + * @param nameIndex Index in constant pool + * @param length Content length in bytes + * @param exceptionIndexTable Table of indices in constant pool + * @param constantPool Array of constants + */ + public ExceptionTable(final int nameIndex, final int length, final int[] exceptionIndexTable, final ConstantPool constantPool) { + super(Const.ATTR_EXCEPTIONS, nameIndex, length, constantPool); + this.exceptionIndexTable = exceptionIndexTable != null ? exceptionIndexTable : Const.EMPTY_INT_ARRAY; + Args.requireU2(this.exceptionIndexTable.length, "exceptionIndexTable.length"); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionTable(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final ExceptionTable c = (ExceptionTable) clone(); + if (exceptionIndexTable != null) { + c.exceptionIndexTable = exceptionIndexTable.clone(); + } + c.setConstantPool(constantPool); + return c; + } /** * Dump exceptions attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(exceptionIndexTable.length); for (final int index : exceptionIndexTable) { @@ -110,7 +128,6 @@ } } - /** * @return Array of indices into constant pool of thrown exceptions. */ @@ -118,36 +135,29 @@ return exceptionIndexTable; } - - /** - * @return Length of exception table. - */ - public int getNumberOfExceptions() { - return exceptionIndexTable == null ? 0 : exceptionIndexTable.length; - } - - /** * @return class names of thrown exceptions */ public String[] getExceptionNames() { final String[] names = new String[exceptionIndexTable.length]; - for (int i = 0; i < exceptionIndexTable.length; i++) { - names[i] = super.getConstantPool().getConstantString(exceptionIndexTable[i], - Const.CONSTANT_Class).replace('/', '.'); - } + Arrays.setAll(names, i -> Utility.pathToPackage(super.getConstantPool().getConstantString(exceptionIndexTable[i], Const.CONSTANT_Class))); return names; } - /** - * @param exceptionIndexTable the list of exception indexes - * Also redefines number_of_exceptions according to table length. + * @return Length of exception table. */ - public void setExceptionIndexTable( final int[] exceptionIndexTable ) { - this.exceptionIndexTable = exceptionIndexTable != null ? exceptionIndexTable : new int[0]; + public int getNumberOfExceptions() { + return exceptionIndexTable == null ? 0 : exceptionIndexTable.length; } + /** + * @param exceptionIndexTable the list of exception indexes Also redefines number_of_exceptions according to table + * length. + */ + public void setExceptionIndexTable(final int[] exceptionIndexTable) { + this.exceptionIndexTable = exceptionIndexTable != null ? exceptionIndexTable : Const.EMPTY_INT_ARRAY; + } /** * @return String representation, i.e., a list of thrown exceptions. @@ -166,20 +176,4 @@ } return buf.toString(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final ExceptionTable c = (ExceptionTable) clone(); - if (exceptionIndexTable != null) { - c.exceptionIndexTable = new int[exceptionIndexTable.length]; - System.arraycopy(exceptionIndexTable, 0, c.exceptionIndexTable, 0, - exceptionIndexTable.length); - } - c.setConstantPool(_constant_pool); - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,75 +30,111 @@ import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * This class represents the field info structure, i.e., the representation - * for a variable in the class. See JVM specification for details. - * + * This class represents the field info structure, i.e., the representation for a variable in the class. See JVM + * specification for details. */ public final class Field extends FieldOrMethod { + /** + * Empty array constant. + * + * @since 6.6.0 + */ + public static final Field[] EMPTY_ARRAY = {}; + private static BCELComparator bcelComparator = new BCELComparator() { @Override - public boolean equals( final Object o1, final Object o2 ) { + public boolean equals(final Object o1, final Object o2) { final Field THIS = (Field) o1; final Field THAT = (Field) o2; - return Objects.equals(THIS.getName(), THAT.getName()) - && Objects.equals(THIS.getSignature(), THAT.getSignature()); + return Objects.equals(THIS.getName(), THAT.getName()) && Objects.equals(THIS.getSignature(), THAT.getSignature()); } - @Override - public int hashCode( final Object o ) { + public int hashCode(final Object o) { final Field THIS = (Field) o; return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); } }; + /** + * Empty array. + */ + static final Field[] EMPTY_FIELD_ARRAY = {}; /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * @return Comparison strategy object */ - public Field(final Field c) { - super(c); + public static BCELComparator getComparator() { + return bcelComparator; } + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } /** * Construct object from file stream. + * * @param file Input stream */ - Field(final DataInput file, final ConstantPool constant_pool) throws IOException, - ClassFormatException { - super(file, constant_pool); + Field(final DataInput file, final ConstantPool constantPool) throws IOException, ClassFormatException { + super(file, constantPool); } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. + */ + public Field(final Field c) { + super(c); + } /** - * @param access_flags Access rights of field - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature + * @param accessFlags Access rights of field + * @param nameIndex Points to field name in constant pool + * @param signatureIndex Points to encoded signature * @param attributes Collection of attributes - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public Field(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes, - final ConstantPool constant_pool) { - super(access_flags, name_index, signature_index, attributes, constant_pool); + public Field(final int accessFlags, final int nameIndex, final int signatureIndex, final Attribute[] attributes, final ConstantPool constantPool) { + super(accessFlags, nameIndex, signatureIndex, attributes, constantPool); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitField(this); } + /** + * @return deep copy of this field + */ + public Field copy(final ConstantPool constantPool) { + return (Field) copy_(constantPool); + } + + /** + * Return value as defined by given BCELComparator strategy. By default two Field objects are said to be equal when + * their names and signatures are equal. + * + * @see Object#equals(Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } /** * @return constant value associated with this field (may be null) @@ -112,10 +148,26 @@ return null; } + /** + * @return type of field + */ + public Type getType() { + return Type.getReturnType(getSignature()); + } + + /** + * Return value as defined by given BCELComparator strategy. By default return the hashcode of the field's name XOR + * signature. + * + * @see Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. + * Return string representation close to declaration format, 'public static final short MAX = 100', e.g.. * * @return String representation of field, including the signature. */ @@ -127,7 +179,7 @@ // Get names from constant pool access = Utility.accessToString(super.getAccessFlags()); - access = access.isEmpty() ? "" : (access + " "); + access = access.isEmpty() ? "" : access + " "; signature = Utility.signatureToString(getSignature()); name = getName(); final StringBuilder buf = new StringBuilder(64); // CHECKSTYLE IGNORE MagicNumber @@ -143,61 +195,4 @@ } return buf.toString(); } - - - /** - * @return deep copy of this field - */ - public Field copy( final ConstantPool _constant_pool ) { - return (Field) copy_(_constant_pool); - } - - - /** - * @return type of field - */ - public Type getType() { - return Type.getReturnType(getSignature()); - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return bcelComparator; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two Field objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals( final Object obj ) { - return bcelComparator.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the field's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return bcelComparator.hashCode(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,7 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; - -import com.sun.org.apache.bcel.internal.Const; +import java.util.Arrays; /** * Abstract super class for fields and methods. @@ -32,89 +31,121 @@ * @LastModified: Jan 2020 */ public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { - private int name_index; // Points to field name in constant pool - private int signature_index; // Points to encoded signature - private Attribute[] attributes; // Collection of attributes - private int attributes_count; // No. of attributes + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected int name_index; // Points to field name in constant pool + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected int signature_index; // Points to encoded signature + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected Attribute[] attributes; // Collection of attributes + + /** + * @deprecated (since 6.0) will be removed (not needed) + */ + @java.lang.Deprecated + protected int attributes_count; // No. of attributes // @since 6.0 private AnnotationEntry[] annotationEntries; // annotations defined on the field or method - private ConstantPool constant_pool; + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @java.lang.Deprecated + protected ConstantPool constant_pool; - private String signatureAttributeString = null; - private boolean searchedForSignatureAttribute = false; + private String signatureAttributeString; + private boolean searchedForSignatureAttribute; FieldOrMethod() { } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException if an I/O error occurs. */ - protected FieldOrMethod(final FieldOrMethod c) { - this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), - c.getAttributes(), c.getConstantPool()); + protected FieldOrMethod(final DataInput file, final ConstantPool constantPool) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, constantPool); + final int attributesCount = file.readUnsignedShort(); + attributes = new Attribute[attributesCount]; + for (int i = 0; i < attributesCount; i++) { + attributes[i] = Attribute.readAttribute(file, constantPool); + } + this.attributes_count = attributesCount; // init deprecated field } - /** * Construct object from file stream. * * @param file Input stream - * @throws IOException - * @throws ClassFormatException + * @throws IOException if an I/O error occurs. * @deprecated (6.0) Use {@link #FieldOrMethod(java.io.DataInput, ConstantPool)} instead. */ @java.lang.Deprecated - protected FieldOrMethod(final DataInputStream file, final ConstantPool constant_pool) - throws IOException, - ClassFormatException { - this((DataInput) file, constant_pool); + protected FieldOrMethod(final DataInputStream file, final ConstantPool constantPool) throws IOException { + this((DataInput) file, constantPool); } /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - * @throws ClassFormatException + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. */ - protected FieldOrMethod(final DataInput file, final ConstantPool constant_pool) - throws IOException, ClassFormatException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, - constant_pool); - final int attributes_count = file.readUnsignedShort(); - attributes = new Attribute[attributes_count]; - for (int i = 0; i < attributes_count; i++) { - attributes[i] = Attribute.readAttribute(file, constant_pool); - } - this.attributes_count = attributes_count; // init deprecated field + protected FieldOrMethod(final FieldOrMethod c) { + this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c.getConstantPool()); } - /** - * @param access_flags Access rights of method - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature + * @param accessFlags Access rights of method + * @param nameIndex Points to field name in constant pool + * @param signatureIndex Points to encoded signature * @param attributes Collection of attributes - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - protected FieldOrMethod(final int access_flags, final int name_index, final int signature_index, - final Attribute[] attributes, final ConstantPool constant_pool) { - super(access_flags); - this.name_index = name_index; - this.signature_index = signature_index; - this.constant_pool = constant_pool; + protected FieldOrMethod(final int accessFlags, final int nameIndex, final int signatureIndex, final Attribute[] attributes, + final ConstantPool constantPool) { + super(accessFlags); + this.name_index = nameIndex; + this.signature_index = signatureIndex; + this.constant_pool = constantPool; setAttributes(attributes); } + /** + * @return deep copy of this field + */ + protected FieldOrMethod copy_(final ConstantPool constantPool) { + try { + final FieldOrMethod c = (FieldOrMethod) clone(); + c.constant_pool = constantPool; + c.attributes = new Attribute[attributes.length]; + c.attributes_count = attributes_count; // init deprecated field + Arrays.setAll(c.attributes, i -> attributes[i].copy(constantPool)); + return c; + } catch (final CloneNotSupportedException e) { + throw new IllegalStateException(e); + } + } /** * Dump object to file stream on binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ public final void dump(final DataOutputStream file) throws IOException { file.writeShort(super.getAccessFlags()); @@ -128,24 +159,25 @@ } } - /** - * @return Collection of object attributes. + * @return Annotations on the field or method + * @since 6.0 */ - public final Attribute[] getAttributes() { - return attributes; - } + public AnnotationEntry[] getAnnotationEntries() { + if (annotationEntries == null) { + annotationEntries = AnnotationEntry.createAnnotationEntries(getAttributes()); + } + return annotationEntries; + } /** - * @param attributes Collection of object attributes. + * @return Collection of object attributes. */ - public final void setAttributes( final Attribute[] attributes ) { - this.attributes = attributes; - this.attributes_count = attributes != null ? attributes.length : 0; // init deprecated field + public final Attribute[] getAttributes() { + return attributes; } - /** * @return Constant pool used by this object. */ @@ -153,14 +185,33 @@ return constant_pool; } - /** - * @param constant_pool Constant pool to be used for this object. + * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be + * (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector<Ljava/lang/String>;' Coded for + * performance - searches for the attribute only when requested - only searches for it once. + * + * @since 6.0 */ - public final void setConstantPool( final ConstantPool constant_pool ) { - this.constant_pool = constant_pool; + public final String getGenericSignature() { + if (!searchedForSignatureAttribute) { + boolean found = false; + for (int i = 0; !found && i < attributes.length; i++) { + if (attributes[i] instanceof Signature) { + signatureAttributeString = ((Signature) attributes[i]).getSignature(); + found = true; + } + } + searchedForSignatureAttribute = true; + } + return signatureAttributeString; } + /** + * @return Name of object, i.e., method name or field name + */ + public final String getName() { + return constant_pool.getConstantUtf8(name_index).getBytes(); + } /** * @return Index in constant pool of object's name. @@ -169,15 +220,13 @@ return name_index; } - /** - * @param name_index Index in constant pool of object's name. + * @return String representation of object's type signature (java style) */ - public final void setNameIndex( final int name_index ) { - this.name_index = name_index; + public final String getSignature() { + return constant_pool.getConstantUtf8(signature_index).getBytes(); } - /** * @return Index in constant pool of field signature. */ @@ -185,96 +234,32 @@ return signature_index; } - - /** - * @param signature_index Index in constant pool of field signature. - */ - public final void setSignatureIndex( final int signature_index ) { - this.signature_index = signature_index; - } - - /** - * @return Name of object, i.e., method name or field name - */ - public final String getName() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8); - return c.getBytes(); - } - - - /** - * @return String representation of object's type signature (java style) + * @param attributes Collection of object attributes. */ - public final String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8) constant_pool.getConstant(signature_index, Const.CONSTANT_Utf8); - return c.getBytes(); + public final void setAttributes(final Attribute[] attributes) { + this.attributes = attributes; + this.attributes_count = attributes != null ? attributes.length : 0; // init deprecated field } - /** - * @return deep copy of this field + * @param constantPool Constant pool to be used for this object. */ - protected FieldOrMethod copy_( final ConstantPool _constant_pool ) { - FieldOrMethod c = null; - - try { - c = (FieldOrMethod)clone(); - } catch(final CloneNotSupportedException e) { - // ignored, but will cause NPE ... - } - - c.constant_pool = constant_pool; - c.attributes = new Attribute[attributes.length]; - c.attributes_count = attributes_count; // init deprecated field - - for (int i = 0; i < attributes.length; i++) { - c.attributes[i] = attributes[i].copy(constant_pool); - } - - return c; + public final void setConstantPool(final ConstantPool constantPool) { + this.constant_pool = constantPool; } /** - * @return Annotations on the field or method - * @since 6.0 + * @param nameIndex Index in constant pool of object's name. */ - public AnnotationEntry[] getAnnotationEntries() { - if (annotationEntries == null) { - annotationEntries = AnnotationEntry.createAnnotationEntries(getAttributes()); - } - - return annotationEntries; + public final void setNameIndex(final int nameIndex) { + this.name_index = nameIndex; } /** - * Hunts for a signature attribute on the member and returns its contents. - * So where the 'regular' signature may be (Ljava/util/Vector;)V the - * signature attribute may in fact say - * 'Ljava/lang/Vector<Ljava/lang/String>;' Coded for performance - - * searches for the attribute only when requested - only searches for it - * once. - * - * @since 6.0 + * @param signatureIndex Index in constant pool of field signature. */ - public final String getGenericSignature() - { - if (!searchedForSignatureAttribute) - { - boolean found = false; - for (int i = 0; !found && i < attributes.length; i++) - { - if (attributes[i] instanceof Signature) - { - signatureAttributeString = ((Signature) attributes[i]) - .getSignature(); - found = true; - } - } - searchedForSignatureAttribute = true; - } - return signatureAttributeString; + public final void setSignatureIndex(final int signatureIndex) { + this.signature_index = signatureIndex; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,93 +24,107 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.stream.Stream; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and denotes that this class - * is an Inner class of another. - * to the source file of this class. - * It is instantiated from the Attribute.readAttribute() method. + * This class is derived from Attribute and denotes that this class is an Inner class of another. to the source + * file of this class. It is instantiated from the Attribute.readAttribute() method. * - * @see Attribute + * @see Attribute */ -public final class InnerClasses extends Attribute { - - private InnerClass[] innerClasses; - +public final class InnerClasses extends Attribute implements Iterable { /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * Empty array. */ - public InnerClasses(final InnerClasses c) { - this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); - } + private static final InnerClass[] EMPTY_INNER_CLASSE_ARRAY = {}; + private InnerClass[] innerClasses; /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param innerClasses array of inner classes attributes - * @param constant_pool Array of constants + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. */ - public InnerClasses(final int name_index, final int length, final InnerClass[] innerClasses, - final ConstantPool constant_pool) { - super(Const.ATTR_INNER_CLASSES, name_index, length, constant_pool); - this.innerClasses = innerClasses != null ? innerClasses : new InnerClass[0]; + public InnerClasses(final InnerClasses c) { + this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); } - /** * Construct object from input stream. * - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - InnerClasses(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, (InnerClass[]) null, constant_pool); - final int number_of_classes = input.readUnsignedShort(); - innerClasses = new InnerClass[number_of_classes]; - for (int i = 0; i < number_of_classes; i++) { + InnerClasses(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (InnerClass[]) null, constantPool); + final int classCount = input.readUnsignedShort(); + innerClasses = new InnerClass[classCount]; + for (int i = 0; i < classCount; i++) { innerClasses[i] = new InnerClass(input); } } + /** + * @param nameIndex Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param innerClasses array of inner classes attributes + * @param constantPool Array of constants + */ + public InnerClasses(final int nameIndex, final int length, final InnerClass[] innerClasses, final ConstantPool constantPool) { + super(Const.ATTR_INNER_CLASSES, nameIndex, length, constantPool); + this.innerClasses = innerClasses != null ? innerClasses : EMPTY_INNER_CLASSE_ARRAY; + Args.requireU2(this.innerClasses.length, "innerClasses.length"); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitInnerClasses(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + // TODO this could be recoded to use a lower level constructor after creating a copy of the inner classes + final InnerClasses c = (InnerClasses) clone(); + c.innerClasses = new InnerClass[innerClasses.length]; + Arrays.setAll(c.innerClasses, i -> innerClasses[i].copy()); + c.setConstantPool(constantPool); + return c; + } /** * Dump source file attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(innerClasses.length); - for (final InnerClass inner_class : innerClasses) { - inner_class.dump(file); + for (final InnerClass innerClass : innerClasses) { + innerClass.dump(file); } } - /** * @return array of inner class "records" */ @@ -118,15 +132,18 @@ return innerClasses; } + @Override + public Iterator iterator() { + return Stream.of(innerClasses).iterator(); + } /** * @param innerClasses the array of inner classes */ - public void setInnerClasses( final InnerClass[] innerClasses ) { - this.innerClasses = innerClasses != null ? innerClasses : new InnerClass[0]; + public void setInnerClasses(final InnerClass[] innerClasses) { + this.innerClasses = innerClasses != null ? innerClasses : EMPTY_INNER_CLASSE_ARRAY; } - /** * @return String representation. */ @@ -136,25 +153,9 @@ buf.append("InnerClasses("); buf.append(innerClasses.length); buf.append("):\n"); - for (final InnerClass inner_class : innerClasses) { - buf.append(inner_class.toString(super.getConstantPool())).append("\n"); + for (final InnerClass innerClass : innerClasses) { + buf.append(innerClass.toString(super.getConstantPool())).append("\n"); } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - // TODO this could be recoded to use a lower level constructor after creating a copy of the inner classes - final InnerClasses c = (InnerClasses) clone(); - c.innerClasses = new InnerClass[innerClasses.length]; - for (int i = 0; i < innerClasses.length; i++) { - c.innerClasses[i] = innerClasses[i].copy(); - } - c.setConstantPool(_constant_pool); - return c; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,9 +28,8 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents a inner class attribute, i.e., the class - * indices of the inner and outer classes, the name and the attributes - * of the inner class. + * This class represents a inner class attribute, i.e., the class indices of the inner and outer classes, the name and + * the attributes of the inner class. * * @see InnerClasses */ @@ -41,69 +40,74 @@ private int innerNameIndex; private int innerAccessFlags; - - /** - * Initialize from another object. - */ - public InnerClass(final InnerClass c) { - this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c - .getInnerAccessFlags()); - } - - /** * Construct object from file stream. + * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ InnerClass(final DataInput file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort()); + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort()); } + /** + * Initialize from another object. + * + * @param c Source to copy. + */ + public InnerClass(final InnerClass c) { + this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c.getInnerAccessFlags()); + } /** * @param innerClassIndex Class index in constant pool of inner class * @param outerClassIndex Class index in constant pool of outer class - * @param innerNameIndex Name index in constant pool of inner class + * @param innerNameIndex Name index in constant pool of inner class * @param innerAccessFlags Access flags of inner class */ - public InnerClass(final int innerClassIndex, final int outerClassIndex, final int innerNameIndex, - final int innerAccessFlags) { + public InnerClass(final int innerClassIndex, final int outerClassIndex, final int innerNameIndex, final int innerAccessFlags) { this.innerClassIndex = innerClassIndex; this.outerClassIndex = outerClassIndex; this.innerNameIndex = innerNameIndex; this.innerAccessFlags = innerAccessFlags; } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitInnerClass(this); } + /** + * @return deep copy of this object + */ + public InnerClass copy() { + try { + return (InnerClass) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } /** * Dump inner class attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(innerClassIndex); file.writeShort(outerClassIndex); file.writeShort(innerNameIndex); file.writeShort(innerAccessFlags); } - /** * @return access flags of inner class. */ @@ -111,7 +115,6 @@ return innerAccessFlags; } - /** * @return class index of inner class. */ @@ -119,7 +122,6 @@ return innerClassIndex; } - /** * @return name index of inner class. */ @@ -127,7 +129,6 @@ return innerNameIndex; } - /** * @return class index of outer class. */ @@ -135,86 +136,63 @@ return outerClassIndex; } - /** * @param innerAccessFlags access flags for this inner class */ - public void setInnerAccessFlags( final int innerAccessFlags ) { + public void setInnerAccessFlags(final int innerAccessFlags) { this.innerAccessFlags = innerAccessFlags; } - /** * @param innerClassIndex index into the constant pool for this class */ - public void setInnerClassIndex( final int innerClassIndex ) { + public void setInnerClassIndex(final int innerClassIndex) { this.innerClassIndex = innerClassIndex; } - /** * @param innerNameIndex index into the constant pool for this class's name */ - public void setInnerNameIndex( final int innerNameIndex ) { // TODO unused + public void setInnerNameIndex(final int innerNameIndex) { // TODO unused this.innerNameIndex = innerNameIndex; } - /** * @param outerClassIndex index into the constant pool for the owning class */ - public void setOuterClassIndex( final int outerClassIndex ) { // TODO unused + public void setOuterClassIndex(final int outerClassIndex) { // TODO unused this.outerClassIndex = outerClassIndex; } - /** * @return String representation. */ @Override public String toString() { - return "InnerClass(" + innerClassIndex + ", " + outerClassIndex + ", " - + innerNameIndex + ", " + innerAccessFlags + ")"; + return "InnerClass(" + innerClassIndex + ", " + outerClassIndex + ", " + innerNameIndex + ", " + innerAccessFlags + ")"; } - /** * @return Resolved string representation */ - public String toString( final ConstantPool constantPool ) { - String outer_class_name; - String inner_name; - String inner_class_name = constantPool.getConstantString(innerClassIndex, - Const.CONSTANT_Class); - inner_class_name = Utility.compactClassName(inner_class_name, false); + public String toString(final ConstantPool constantPool) { + String outerClassName; + String innerName; + String innerClassName = constantPool.getConstantString(innerClassIndex, Const.CONSTANT_Class); + innerClassName = Utility.compactClassName(innerClassName, false); if (outerClassIndex != 0) { - outer_class_name = constantPool.getConstantString(outerClassIndex, - Const.CONSTANT_Class); - outer_class_name = " of class " + Utility.compactClassName(outer_class_name, false); + outerClassName = constantPool.getConstantString(outerClassIndex, Const.CONSTANT_Class); + outerClassName = " of class " + Utility.compactClassName(outerClassName, false); } else { - outer_class_name = ""; + outerClassName = ""; } if (innerNameIndex != 0) { - inner_name = ((ConstantUtf8) constantPool.getConstant(innerNameIndex, - Const.CONSTANT_Utf8)).getBytes(); + innerName = constantPool.getConstantUtf8(innerNameIndex).getBytes(); } else { - inner_name = "(anonymous)"; + innerName = "(anonymous)"; } String access = Utility.accessToString(innerAccessFlags, true); - access = access.isEmpty() ? "" : (access + " "); - return " " + access + inner_name + "=class " + inner_class_name + outer_class_name; - } - - - /** - * @return deep copy of this object - */ - public InnerClass copy() { - try { - return (InnerClass) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; + access = access.isEmpty() ? "" : access + " "; + return " " + access + innerName + "=class " + innerClassName + outerClassName; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,10 +26,11 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; -import java.util.Objects; -import java.util.StringTokenizer; +import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.StringTokenizer; import java.util.TreeSet; import com.sun.org.apache.bcel.internal.Const; @@ -39,20 +40,74 @@ import com.sun.org.apache.bcel.internal.util.SyntheticRepository; /** - * Represents a Java class, i.e., the data structures, constant pool, - * fields, methods and commands contained in a Java .class file. - * See JVM specification for details. - * The intent of this class is to represent a parsed or otherwise existing - * class file. Those interested in programatically generating classes - * should see the ClassGen class. - + * Represents a Java class, i.e., the data structures, constant pool, fields, methods and commands contained in a Java + * .class file. See JVM specification for details. The intent of + * this class is to represent a parsed or otherwise existing class file. Those interested in programmatically generating + * classes should see the ClassGen class. + * * @see com.sun.org.apache.bcel.internal.generic.ClassGen - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable { + /** + * The standard class file extension. + * + * @since 6.7.0 + */ + public static final String EXTENSION = ".class"; + + /** + * Empty array. + * + * @since 6.6.0 + */ + public static final JavaClass[] EMPTY_ARRAY = {}; + + public static final byte HEAP = 1; + public static final byte FILE = 2; + public static final byte ZIP = 3; + private static BCELComparator bcelComparator = new BCELComparator() { + + @Override + public boolean equals(final Object o1, final Object o2) { + final JavaClass THIS = (JavaClass) o1; + final JavaClass THAT = (JavaClass) o2; + return Objects.equals(THIS.getClassName(), THAT.getClassName()); + } + + @Override + public int hashCode(final Object o) { + final JavaClass THIS = (JavaClass) o; + return THIS.getClassName().hashCode(); + } + }; + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + private static String indent(final Object obj) { + final StringTokenizer tokenizer = new StringTokenizer(obj.toString(), "\n"); + final StringBuilder buf = new StringBuilder(); + while (tokenizer.hasMoreTokens()) { + buf.append("\t").append(tokenizer.nextToken()).append("\n"); + } + return buf.toString(); + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + private String fileName; - private String packageName; + private final String packageName; private String sourceFileName = ""; private int classNameIndex; private int superclassNameIndex; @@ -66,52 +121,52 @@ private Field[] fields; // Fields, i.e., variables of class private Method[] methods; // methods defined in the class private Attribute[] attributes; // attributes defined in the class - private AnnotationEntry[] annotations; // annotations defined on the class + + private AnnotationEntry[] annotations; // annotations defined on the class private byte source = HEAP; // Generated in memory - private boolean isAnonymous = false; - private boolean isNested = false; - private boolean computedNestedTypeStatus = false; - public static final byte HEAP = 1; - public static final byte FILE = 2; - public static final byte ZIP = 3; - private static final boolean debug = false; - private static BCELComparator bcelComparator = new BCELComparator() { + private boolean isAnonymous; - @Override - public boolean equals( final Object o1, final Object o2 ) { - final JavaClass THIS = (JavaClass) o1; - final JavaClass THAT = (JavaClass) o2; - return Objects.equals(THIS.getClassName(), THAT.getClassName()); - } + private boolean isNested; + private boolean computedNestedTypeStatus; - @Override - public int hashCode( final Object o ) { - final JavaClass THIS = (JavaClass) o; - return THIS.getClassName().hashCode(); - } - }; /** - * In cases where we go ahead and create something, - * use the default SyntheticRepository, because we - * don't know any better. + * In cases where we go ahead and create something, use the default SyntheticRepository, because we don't know any + * better. */ - private transient com.sun.org.apache.bcel.internal.util.Repository repository - = SyntheticRepository.getInstance(); + private transient com.sun.org.apache.bcel.internal.util.Repository repository = SyntheticRepository.getInstance(); + /** + * Constructor gets all contents as arguments. + * + * @param classNameIndex Class name + * @param superclassNameIndex Superclass name + * @param fileName File name + * @param major Major compiler version + * @param minor Minor compiler version + * @param accessFlags Access rights defined by bit flags + * @param constantPool Array of constants + * @param interfaces Implemented interfaces + * @param fields Class fields + * @param methods Class methods + * @param attributes Class attributes + */ + public JavaClass(final int classNameIndex, final int superclassNameIndex, final String fileName, final int major, final int minor, final int accessFlags, + final ConstantPool constantPool, final int[] interfaces, final Field[] fields, final Method[] methods, final Attribute[] attributes) { + this(classNameIndex, superclassNameIndex, fileName, major, minor, accessFlags, constantPool, interfaces, fields, methods, attributes, HEAP); + } /** * Constructor gets all contents as arguments. * - * @param classNameIndex Index into constant pool referencing a - * ConstantClass that represents this class. - * @param superclassNameIndex Index into constant pool referencing a - * ConstantClass that represents this class's superclass. + * @param classNameIndex Index into constant pool referencing a ConstantClass that represents this class. + * @param superclassNameIndex Index into constant pool referencing a ConstantClass that represents this class's + * superclass. * @param fileName File name * @param major Major compiler version * @param minor Minor compiler version - * @param access_flags Access rights defined by bit flags + * @param accessFlags Access rights defined by bit flags * @param constantPool Array of constants * @param interfaces Implemented interfaces * @param fields Class fields @@ -119,22 +174,20 @@ * @param attributes Class attributes * @param source Read from file or generated in memory? */ - public JavaClass(final int classNameIndex, final int superclassNameIndex, - final String fileName, final int major, final int minor, final int access_flags, - final ConstantPool constantPool, int[] interfaces, Field[] fields, - Method[] methods, Attribute[] attributes, final byte source) { - super(access_flags); + public JavaClass(final int classNameIndex, final int superclassNameIndex, final String fileName, final int major, final int minor, final int accessFlags, + final ConstantPool constantPool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes, final byte source) { + super(accessFlags); if (interfaces == null) { - interfaces = new int[0]; + interfaces = Const.EMPTY_INT_ARRAY; } if (attributes == null) { - attributes = new Attribute[0]; + attributes = Attribute.EMPTY_ARRAY; } if (fields == null) { - fields = new Field[0]; + fields = Field.EMPTY_FIELD_ARRAY; } if (methods == null) { - methods = new Method[0]; + methods = Method.EMPTY_METHOD_ARRAY; } this.classNameIndex = classNameIndex; this.superclassNameIndex = superclassNameIndex; @@ -154,9 +207,9 @@ break; } } - /* According to the specification the following entries must be of type - * `ConstantClass' but we check that anyway via the - * `ConstPool.getConstant' method. + /* + * According to the specification the following entries must be of type 'ConstantClass' but we check that anyway via the + * 'ConstPool.getConstant' method. */ className = constantPool.getConstantString(classNameIndex, Const.CONSTANT_Class); className = Utility.compactClassName(className, false); @@ -168,8 +221,7 @@ } if (superclassNameIndex > 0) { // May be zero -> class is java.lang.Object - superclassName = constantPool.getConstantString(superclassNameIndex, - Const.CONSTANT_Class); + superclassName = constantPool.getConstantString(superclassNameIndex, Const.CONSTANT_Class); superclassName = Utility.compactClassName(superclassName, false); } else { superclassName = "java.lang.Object"; @@ -181,125 +233,80 @@ } } - /** - * Constructor gets all contents as arguments. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * - * @param classNameIndex Class name - * @param superclassNameIndex Superclass name - * @param fileName File name - * @param major Major compiler version - * @param minor Minor compiler version - * @param access_flags Access rights defined by bit flags - * @param constantPool Array of constants - * @param interfaces Implemented interfaces - * @param fields Class fields - * @param methods Class methods - * @param attributes Class attributes + * @param v Visitor object */ - public JavaClass(final int classNameIndex, final int superclassNameIndex, - final String fileName, final int major, final int minor, final int access_flags, - final ConstantPool constantPool, final int[] interfaces, final Field[] fields, - final Method[] methods, final Attribute[] attributes) { - this(classNameIndex, superclassNameIndex, fileName, major, minor, access_flags, - constantPool, interfaces, fields, methods, attributes, HEAP); + @Override + public void accept(final Visitor v) { + v.visitJavaClass(this); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Return the natural ordering of two JavaClasses. This ordering is based on the class name * - * @param v Visitor object + * @since 6.0 */ @Override - public void accept( final Visitor v ) { - v.visitJavaClass(this); + public int compareTo(final JavaClass obj) { + return getClassName().compareTo(obj.getClassName()); } - - /* Print debug information depending on `JavaClass.debug' - */ - static void Debug( final String str ) { - if (debug) { - System.out.println(str); + private void computeNestedTypeStatus() { + if (computedNestedTypeStatus) { + return; } - } - - - /** - * Dump class to a file. - * - * @param file Output file - * @throws IOException - */ - public void dump(final File file) throws IOException { - final String parent = file.getParent(); - if (parent != null) { - final File dir = new File(parent); - if (!dir.mkdirs()) { // either was not created or already existed - if (!dir.isDirectory()) { - throw new IOException("Could not create the directory " + dir); - } + for (final Attribute attribute : this.attributes) { + if (attribute instanceof InnerClasses) { + ((InnerClasses) attribute).forEach(innerClass -> { + boolean innerClassAttributeRefersToMe = false; + String innerClassName = constantPool.getConstantString(innerClass.getInnerClassIndex(), Const.CONSTANT_Class); + innerClassName = Utility.compactClassName(innerClassName, false); + if (innerClassName.equals(getClassName())) { + innerClassAttributeRefersToMe = true; + } + if (innerClassAttributeRefersToMe) { + this.isNested = true; + if (innerClass.getInnerNameIndex() == 0) { + this.isAnonymous = true; + } + } + }); } } - try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) { - dump(dos); - } - } - - - /** - * Dump class to a file named fileName. - * - * @param _file_name Output file name - * @throws IOException - */ - public void dump( final String _file_name ) throws IOException { - dump(new File(_file_name)); + this.computedNestedTypeStatus = true; } - /** - * @return class in binary format + * @return deep copy of this class */ - public byte[] getBytes() { - final ByteArrayOutputStream s = new ByteArrayOutputStream(); - final DataOutputStream ds = new DataOutputStream(s); + public JavaClass copy() { try { - dump(ds); - } catch (final IOException e) { - System.err.println("Error dumping class: " + e.getMessage()); - } finally { - try { - ds.close(); - } catch (final IOException e2) { - System.err.println("Error dumping class: " + e2.getMessage()); - } + final JavaClass c = (JavaClass) clone(); + c.constantPool = constantPool.copy(); + c.interfaces = interfaces.clone(); + c.interfaceNames = interfaceNames.clone(); + c.fields = new Field[fields.length]; + Arrays.setAll(c.fields, i -> fields[i].copy(c.constantPool)); + c.methods = new Method[methods.length]; + Arrays.setAll(c.methods, i -> methods[i].copy(c.constantPool)); + c.attributes = new Attribute[attributes.length]; + Arrays.setAll(c.attributes, i -> attributes[i].copy(c.constantPool)); + return c; + } catch (final CloneNotSupportedException e) { + return null; } - return s.toByteArray(); } - - /** - * Dump Java class to output stream in binary format. - * - * @param file Output stream - * @throws IOException - */ - public void dump( final OutputStream file ) throws IOException { - dump(new DataOutputStream(file)); - } - - /** * Dump Java class to output stream in binary format. * * @param file Output stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeInt(Const.JVM_CLASSFILE_MAGIC); file.writeShort(minor); file.writeShort(major); @@ -330,12 +337,79 @@ file.flush(); } + /** + * Dump class to a file. + * + * @param file Output file + * @throws IOException if an I/O error occurs. + */ + public void dump(final File file) throws IOException { + final String parent = file.getParent(); + if (parent != null) { + final File dir = new File(parent); + if (!dir.mkdirs() && !dir.isDirectory()) { + throw new IOException("Could not create the directory " + dir); + } + } + try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) { + dump(dos); + } + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file Output stream + * @throws IOException if an I/O error occurs. + */ + public void dump(final OutputStream file) throws IOException { + dump(new DataOutputStream(file)); + } + + /** + * Dump class to a file named fileName. + * + * @param fileName Output file name + * @throws IOException if an I/O error occurs. + */ + public void dump(final String fileName) throws IOException { + dump(new File(fileName)); + } /** - * @return Attributes of the class. + * Return value as defined by given BCELComparator strategy. By default two JavaClass objects are said to be equal when + * their class names are equal. + * + * @see Object#equals(Object) */ - public Attribute[] getAttributes() { - return attributes; + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * Get all interfaces implemented by this JavaClass (transitively). + * + * @throws ClassNotFoundException if any of the class's superclasses or interfaces can't be found. + */ + public JavaClass[] getAllInterfaces() throws ClassNotFoundException { + final ClassQueue queue = new ClassQueue(); + final Set allInterfaces = new TreeSet<>(); + queue.enqueue(this); + while (!queue.empty()) { + final JavaClass clazz = queue.dequeue(); + final JavaClass souper = clazz.getSuperClass(); + final JavaClass[] interfaces = clazz.getInterfaces(); + if (clazz.isInterface()) { + allInterfaces.add(clazz); + } else if (souper != null) { + queue.enqueue(souper); + } + for (final JavaClass iface : interfaces) { + queue.enqueue(iface); + } + } + return allInterfaces.toArray(JavaClass.EMPTY_ARRAY); } /** @@ -351,20 +425,31 @@ } /** - * @return Class name. + * @return Attributes of the class. */ - public String getClassName() { - return className; + public Attribute[] getAttributes() { + return attributes; } - /** - * @return Package name. + * @return class in binary format */ - public String getPackageName() { - return packageName; + public byte[] getBytes() { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try (DataOutputStream dos = new DataOutputStream(baos)) { + dump(dos); + } catch (final IOException e) { + e.printStackTrace(); + } + return baos.toByteArray(); } + /** + * @return Class name. + */ + public String getClassName() { + return className; + } /** * @return Class name index. @@ -373,7 +458,6 @@ return classNameIndex; } - /** * @return Constant pool. */ @@ -381,17 +465,14 @@ return constantPool; } - /** - * @return Fields, i.e., variables of the class. Like the JVM spec - * mandates for the classfile format, these fields are those specific to - * this class, and not those of the superclass or superinterfaces. + * @return Fields, i.e., variables of the class. Like the JVM spec mandates for the classfile format, these fields are + * those specific to this class, and not those of the superclass or superinterfaces. */ public Field[] getFields() { return fields; } - /** * @return File name of class, aka SourceFile attribute value */ @@ -399,6 +480,12 @@ return fileName; } + /** + * @return Indices in constant pool of implemented interfaces. + */ + public int[] getInterfaceIndices() { + return interfaces; + } /** * @return Names of implemented interfaces. @@ -407,15 +494,20 @@ return interfaceNames; } - /** - * @return Indices in constant pool of implemented interfaces. + * Get interfaces directly implemented by this JavaClass. + * + * @throws ClassNotFoundException if any of the class's interfaces can't be found. */ - public int[] getInterfaceIndices() { - return interfaces; + public JavaClass[] getInterfaces() throws ClassNotFoundException { + final String[] interfaces = getInterfaceNames(); + final JavaClass[] classes = new JavaClass[interfaces.length]; + for (int i = 0; i < interfaces.length; i++) { + classes[i] = repository.loadClass(interfaces[i]); + } + return classes; } - /** * @return Major number of class file version. */ @@ -423,29 +515,24 @@ return major; } - /** - * @return Methods of the class. + * @return A {@link Method} corresponding to java.lang.reflect.Method if any */ - public Method[] getMethods() { - return methods; - } - - - /** - * @return A {@link Method} corresponding to - * java.lang.reflect.Method if any - */ - public Method getMethod( final java.lang.reflect.Method m ) { + public Method getMethod(final java.lang.reflect.Method m) { for (final Method method : methods) { - if (m.getName().equals(method.getName()) && (m.getModifiers() == method.getModifiers()) - && Type.getSignature(m).equals(method.getSignature())) { + if (m.getName().equals(method.getName()) && m.getModifiers() == method.getModifiers() && Type.getSignature(m).equals(method.getSignature())) { return method; } } return null; } + /** + * @return Methods of the class. + */ + public Method[] getMethods() { + return methods; + } /** * @return Minor number of class file version. @@ -454,19 +541,78 @@ return minor; } + /** + * @return Package name. + */ + public String getPackageName() { + return packageName; + } + + /** + * Gets the ClassRepository which holds its definition. By default this is the same as + * SyntheticRepository.getInstance(); + */ + public com.sun.org.apache.bcel.internal.util.Repository getRepository() { + return repository; + } + + /** + * @return returns either HEAP (generated), FILE, or ZIP + */ + public final byte getSource() { + return source; + } /** - * @return sbsolute path to file where this class was read from + * @return file name where this class was read from */ public String getSourceFileName() { return sourceFileName; } + /** + * Gets the source file path including the package path. + * + * @return path to original source file of parsed class, relative to original source directory. + * @since 6.7.0 + */ + public String getSourceFilePath() { + final StringBuilder outFileName = new StringBuilder(); + if (!packageName.isEmpty()) { + outFileName.append(Utility.packageToPath(packageName)); + outFileName.append('/'); + } + outFileName.append(sourceFileName); + return outFileName.toString(); + } /** - * returns the super class name of this class. In the case that this class is - * java.lang.Object, it will return itself (java.lang.Object). This is probably incorrect - * but isn't fixed at this time to not break existing clients. + * @return the superclass for this JavaClass object, or null if this is java.lang.Object + * @throws ClassNotFoundException if the superclass can't be found + */ + public JavaClass getSuperClass() throws ClassNotFoundException { + if ("java.lang.Object".equals(getClassName())) { + return null; + } + return repository.loadClass(getSuperclassName()); + } + + /** + * @return list of super classes of this class in ascending order, i.e., java.lang.Object is always the last element + * @throws ClassNotFoundException if any of the superclasses can't be found + */ + public JavaClass[] getSuperClasses() throws ClassNotFoundException { + JavaClass clazz = this; + final List allSuperClasses = new ArrayList<>(); + for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { + allSuperClasses.add(clazz); + } + return allSuperClasses.toArray(JavaClass.EMPTY_ARRAY); + } + + /** + * returns the super class name of this class. In the case that this class is java.lang.Object, it will return itself + * (java.lang.Object). This is probably incorrect but isn't fixed at this time to not break existing clients. * * @return Superclass name. */ @@ -474,7 +620,6 @@ return superclassName; } - /** * @return Class name index. */ @@ -483,128 +628,195 @@ } /** + * Return value as defined by given BCELComparator strategy. By default return the hashcode of the class name. + * + * @see Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } + + /** + * @return true, if this class is an implementation of interface inter + * @throws ClassNotFoundException if superclasses or superinterfaces of this class can't be found + */ + public boolean implementationOf(final JavaClass inter) throws ClassNotFoundException { + if (!inter.isInterface()) { + throw new IllegalArgumentException(inter.getClassName() + " is no interface"); + } + if (this.equals(inter)) { + return true; + } + final JavaClass[] superInterfaces = getAllInterfaces(); + for (final JavaClass superInterface : superInterfaces) { + if (superInterface.equals(inter)) { + return true; + } + } + return false; + } + + /** + * Equivalent to runtime "instanceof" operator. + * + * @return true if this JavaClass is derived from the super class + * @throws ClassNotFoundException if superclasses or superinterfaces of this object can't be found + */ + public final boolean instanceOf(final JavaClass superclass) throws ClassNotFoundException { + if (this.equals(superclass)) { + return true; + } + for (final JavaClass clazz : getSuperClasses()) { + if (clazz.equals(superclass)) { + return true; + } + } + if (superclass.isInterface()) { + return implementationOf(superclass); + } + return false; + } + + /** + * @since 6.0 + */ + public final boolean isAnonymous() { + computeNestedTypeStatus(); + return this.isAnonymous; + } + + public final boolean isClass() { + return (super.getAccessFlags() & Const.ACC_INTERFACE) == 0; + } + + /** + * @since 6.0 + */ + public final boolean isNested() { + computeNestedTypeStatus(); + return this.isNested; + } + + public final boolean isSuper() { + return (super.getAccessFlags() & Const.ACC_SUPER) != 0; + } + + /** * @param attributes . */ - public void setAttributes( final Attribute[] attributes ) { + public void setAttributes(final Attribute[] attributes) { this.attributes = attributes; } - /** * @param className . */ - public void setClassName( final String className ) { + public void setClassName(final String className) { this.className = className; } - /** * @param classNameIndex . */ - public void setClassNameIndex( final int classNameIndex ) { + public void setClassNameIndex(final int classNameIndex) { this.classNameIndex = classNameIndex; } - /** * @param constantPool . */ - public void setConstantPool( final ConstantPool constantPool ) { + public void setConstantPool(final ConstantPool constantPool) { this.constantPool = constantPool; } - /** * @param fields . */ - public void setFields( final Field[] fields ) { + public void setFields(final Field[] fields) { this.fields = fields; } - /** * Set File name of class, aka SourceFile attribute value */ - public void setFileName( final String fileName ) { + public void setFileName(final String fileName) { this.fileName = fileName; } - /** * @param interfaceNames . */ - public void setInterfaceNames( final String[] interfaceNames ) { + public void setInterfaceNames(final String[] interfaceNames) { this.interfaceNames = interfaceNames; } - /** * @param interfaces . */ - public void setInterfaces( final int[] interfaces ) { + public void setInterfaces(final int[] interfaces) { this.interfaces = interfaces; } - /** * @param major . */ - public void setMajor( final int major ) { + public void setMajor(final int major) { this.major = major; } - /** * @param methods . */ - public void setMethods( final Method[] methods ) { + public void setMethods(final Method[] methods) { this.methods = methods; } - /** * @param minor . */ - public void setMinor( final int minor ) { + public void setMinor(final int minor) { this.minor = minor; } + /** + * Sets the ClassRepository which loaded the JavaClass. Should be called immediately after parsing is done. + */ + public void setRepository(final com.sun.org.apache.bcel.internal.util.Repository repository) { // TODO make protected? + this.repository = repository; + } /** * Set absolute path to file this class was read from. */ - public void setSourceFileName( final String sourceFileName ) { + public void setSourceFileName(final String sourceFileName) { this.sourceFileName = sourceFileName; } - /** * @param superclassName . */ - public void setSuperclassName( final String superclassName ) { + public void setSuperclassName(final String superclassName) { this.superclassName = superclassName; } - /** * @param superclassNameIndex . */ - public void setSuperclassNameIndex( final int superclassNameIndex ) { + public void setSuperclassNameIndex(final int superclassNameIndex) { this.superclassNameIndex = superclassNameIndex; } - /** * @return String representing class contents. */ @Override public String toString() { String access = Utility.accessToString(super.getAccessFlags(), true); - access = access.isEmpty() ? "" : (access + " "); + access = access.isEmpty() ? "" : access + " "; final StringBuilder buf = new StringBuilder(128); - buf.append(access).append(Utility.classOrInterface(super.getAccessFlags())).append(" ").append( - className).append(" extends ").append( - Utility.compactClassName(superclassName, false)).append('\n'); + buf.append(access).append(Utility.classOrInterface(super.getAccessFlags())).append(" ").append(className).append(" extends ") + .append(Utility.compactClassName(superclassName, false)).append('\n'); final int size = interfaces.length; if (size > 0) { buf.append("implements\t\t"); @@ -629,7 +841,7 @@ } } final AnnotationEntry[] annotations = getAnnotationEntries(); - if (annotations!=null && annotations.length>0) { + if (annotations != null && annotations.length > 0) { buf.append("\nAnnotation(s):\n"); for (final AnnotationEntry annotation : annotations) { buf.append(indent(annotation)); @@ -649,286 +861,4 @@ } return buf.toString(); } - - - private static String indent( final Object obj ) { - final StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); - final StringBuilder buf = new StringBuilder(); - while (tok.hasMoreTokens()) { - buf.append("\t").append(tok.nextToken()).append("\n"); - } - return buf.toString(); - } - - - /** - * @return deep copy of this class - */ - public JavaClass copy() { - JavaClass c = null; - try { - c = (JavaClass) clone(); - c.constantPool = constantPool.copy(); - c.interfaces = interfaces.clone(); - c.interfaceNames = interfaceNames.clone(); - c.fields = new Field[fields.length]; - for (int i = 0; i < fields.length; i++) { - c.fields[i] = fields[i].copy(c.constantPool); - } - c.methods = new Method[methods.length]; - for (int i = 0; i < methods.length; i++) { - c.methods[i] = methods[i].copy(c.constantPool); - } - c.attributes = new Attribute[attributes.length]; - for (int i = 0; i < attributes.length; i++) { - c.attributes[i] = attributes[i].copy(c.constantPool); - } - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return c; - } - - - public final boolean isSuper() { - return (super.getAccessFlags() & Const.ACC_SUPER) != 0; - } - - - public final boolean isClass() { - return (super.getAccessFlags() & Const.ACC_INTERFACE) == 0; - } - - /** - * @since 6.0 - */ - public final boolean isAnonymous() { - computeNestedTypeStatus(); - return this.isAnonymous; - } - - /** - * @since 6.0 - */ - public final boolean isNested() { - computeNestedTypeStatus(); - return this.isNested; - } - - private void computeNestedTypeStatus() { - if (computedNestedTypeStatus) { - return; - } - for (final Attribute attribute : this.attributes) { - if (attribute instanceof InnerClasses) { - final InnerClass[] innerClasses = ((InnerClasses) attribute).getInnerClasses(); - for (final InnerClass innerClasse : innerClasses) { - boolean innerClassAttributeRefersToMe = false; - String inner_class_name = constantPool.getConstantString(innerClasse.getInnerClassIndex(), - Const.CONSTANT_Class); - inner_class_name = Utility.compactClassName(inner_class_name, false); - if (inner_class_name.equals(getClassName())) { - innerClassAttributeRefersToMe = true; - } - if (innerClassAttributeRefersToMe) { - this.isNested = true; - if (innerClasse.getInnerNameIndex() == 0) { - this.isAnonymous = true; - } - } - } - } - } - this.computedNestedTypeStatus = true; - } - - - /** @return returns either HEAP (generated), FILE, or ZIP - */ - public final byte getSource() { - return source; - } - - - /********************* New repository functionality *********************/ - /** - * Gets the ClassRepository which holds its definition. By default - * this is the same as SyntheticRepository.getInstance(); - */ - public com.sun.org.apache.bcel.internal.util.Repository getRepository() { - return repository; - } - - - /** - * Sets the ClassRepository which loaded the JavaClass. - * Should be called immediately after parsing is done. - */ - public void setRepository( final com.sun.org.apache.bcel.internal.util.Repository repository ) { // TODO make protected? - this.repository = repository; - } - - - /** Equivalent to runtime "instanceof" operator. - * - * @return true if this JavaClass is derived from the super class - * @throws ClassNotFoundException if superclasses or superinterfaces - * of this object can't be found - */ - public final boolean instanceOf( final JavaClass super_class ) throws ClassNotFoundException { - if (this.equals(super_class)) { - return true; - } - final JavaClass[] super_classes = getSuperClasses(); - for (final JavaClass super_classe : super_classes) { - if (super_classe.equals(super_class)) { - return true; - } - } - if (super_class.isInterface()) { - return implementationOf(super_class); - } - return false; - } - - - /** - * @return true, if this class is an implementation of interface inter - * @throws ClassNotFoundException if superclasses or superinterfaces - * of this class can't be found - */ - public boolean implementationOf( final JavaClass inter ) throws ClassNotFoundException { - if (!inter.isInterface()) { - throw new IllegalArgumentException(inter.getClassName() + " is no interface"); - } - if (this.equals(inter)) { - return true; - } - final JavaClass[] super_interfaces = getAllInterfaces(); - for (final JavaClass super_interface : super_interfaces) { - if (super_interface.equals(inter)) { - return true; - } - } - return false; - } - - - /** - * @return the superclass for this JavaClass object, or null if this - * is java.lang.Object - * @throws ClassNotFoundException if the superclass can't be found - */ - public JavaClass getSuperClass() throws ClassNotFoundException { - if ("java.lang.Object".equals(getClassName())) { - return null; - } - return repository.loadClass(getSuperclassName()); - } - - - /** - * @return list of super classes of this class in ascending order, i.e., - * java.lang.Object is always the last element - * @throws ClassNotFoundException if any of the superclasses can't be found - */ - public JavaClass[] getSuperClasses() throws ClassNotFoundException { - JavaClass clazz = this; - final List allSuperClasses = new ArrayList<>(); - for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { - allSuperClasses.add(clazz); - } - return allSuperClasses.toArray(new JavaClass[allSuperClasses.size()]); - } - - - /** - * Get interfaces directly implemented by this JavaClass. - */ - public JavaClass[] getInterfaces() throws ClassNotFoundException { - final String[] _interfaces = getInterfaceNames(); - final JavaClass[] classes = new JavaClass[_interfaces.length]; - for (int i = 0; i < _interfaces.length; i++) { - classes[i] = repository.loadClass(_interfaces[i]); - } - return classes; - } - - - /** - * Get all interfaces implemented by this JavaClass (transitively). - */ - public JavaClass[] getAllInterfaces() throws ClassNotFoundException { - final ClassQueue queue = new ClassQueue(); - final Set allInterfaces = new TreeSet<>(); - queue.enqueue(this); - while (!queue.empty()) { - final JavaClass clazz = queue.dequeue(); - final JavaClass souper = clazz.getSuperClass(); - final JavaClass[] _interfaces = clazz.getInterfaces(); - if (clazz.isInterface()) { - allInterfaces.add(clazz); - } else { - if (souper != null) { - queue.enqueue(souper); - } - } - for (final JavaClass _interface : _interfaces) { - queue.enqueue(_interface); - } - } - return allInterfaces.toArray(new JavaClass[allInterfaces.size()]); - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return bcelComparator; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two JavaClass objects are said to be equal when - * their class names are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals( final Object obj ) { - return bcelComparator.equals(this, obj); - } - - - /** - * Return the natural ordering of two JavaClasses. - * This ordering is based on the class name - * @since 6.0 - */ - @Override - public int compareTo( final JavaClass obj ) { - return getClassName().compareTo(obj.getClassName()); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the class name. - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return bcelComparator.hashCode(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,30 +25,23 @@ import java.io.DataOutputStream; import java.io.IOException; +import com.sun.org.apache.bcel.internal.util.Args; + /** - * This class represents a (PC offset, line number) pair, i.e., a line number in - * the source that corresponds to a relative address in the byte code. This - * is used for debugging purposes. + * This class represents a (PC offset, line number) pair, i.e., a line number in the source that corresponds to a + * relative address in the byte code. This is used for debugging purposes. * - * @see LineNumberTable + * @see LineNumberTable */ public final class LineNumber implements Cloneable, Node { + static final LineNumber[] EMPTY_ARRAY = {}; + /** Program Counter (PC) corresponds to line */ - private short startPc; + private int startPc; /** number in source file */ - private short lineNumber; - - /** - * Initialize from another object. - * - * @param c the object to copy - */ - public LineNumber(final LineNumber c) { - this(c.getStartPC(), c.getLineNumber()); - } - + private int lineNumber; /** * Construct object from file stream. @@ -60,29 +53,46 @@ this(file.readUnsignedShort(), file.readUnsignedShort()); } - /** * @param startPc Program Counter (PC) corresponds to * @param lineNumber line number in source file */ public LineNumber(final int startPc, final int lineNumber) { - this.startPc = (short) startPc; - this.lineNumber = (short)lineNumber; + this.startPc = Args.requireU2(startPc, "startPc"); + this.lineNumber = Args.requireU2(lineNumber, "lineNumber"); } + /** + * Initialize from another object. + * + * @param c the object to copy + */ + public LineNumber(final LineNumber c) { + this(c.getStartPC(), c.getLineNumber()); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLineNumber(this); } + /** + * @return deep copy of this object + */ + public LineNumber copy() { + try { + return (LineNumber) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } /** * Dump line number/pc pair to file stream in binary format. @@ -90,62 +100,44 @@ * @param file Output file stream * @throws IOException if an I/O Exception occurs in writeShort */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(startPc); file.writeShort(lineNumber); } - /** * @return Corresponding source line */ public int getLineNumber() { - return 0xffff & lineNumber; + return lineNumber & 0xffff; } - /** * @return PC in code */ public int getStartPC() { - return 0xffff & startPc; + return startPc & 0xffff; } - /** * @param lineNumber the source line number */ - public void setLineNumber( final int lineNumber ) { + public void setLineNumber(final int lineNumber) { this.lineNumber = (short) lineNumber; } - /** * @param startPc the pc for this line number */ - public void setStartPC( final int startPc ) { + public void setStartPC(final int startPc) { this.startPc = (short) startPc; } - /** * @return String representation */ @Override public String toString() { - return "LineNumber(" + startPc + ", " + lineNumber + ")"; - } - - - /** - * @return deep copy of this object - */ - public LineNumber copy() { - try { - return (LineNumber) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; + return "LineNumber(" + getStartPC() + ", " + getLineNumber() + ")"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java 2023-10-06 05:33:33.000000000 +0000 @@ -19,86 +19,104 @@ */ package com.sun.org.apache.bcel.internal.classfile; -import com.sun.org.apache.bcel.internal.Const; import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.stream.Stream; + +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; import jdk.xml.internal.SecuritySupport; /** - * This class represents a table of line numbers for debugging - * purposes. This attribute is used by the Code attribute. It - * contains pairs of PCs and line numbers. + * This class represents a table of line numbers for debugging purposes. This attribute is used by the Code + * attribute. It contains pairs of PCs and line numbers. * - * @see Code + * @see Code * @see LineNumber * @LastModified: May 2021 */ -public final class LineNumberTable extends Attribute { +public final class LineNumberTable extends Attribute implements Iterable { private static final int MAX_LINE_LENGTH = 72; private LineNumber[] lineNumberTable; // Table of line/numbers pairs - - /* - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + /** + * Construct object from input stream. + * + * @param nameIndex Index of name + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O Exception occurs in readUnsignedShort */ - public LineNumberTable(final LineNumberTable c) { - this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); + LineNumberTable(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (LineNumber[]) null, constantPool); + final int lineNumberTableLength = input.readUnsignedShort(); + lineNumberTable = new LineNumber[lineNumberTableLength]; + for (int i = 0; i < lineNumberTableLength; i++) { + lineNumberTable[i] = new LineNumber(input); + } } - /* - * @param name_index Index of name + * @param nameIndex Index of name + * * @param length Content length in bytes + * * @param lineNumberTable Table of line/numbers pairs - * @param constant_pool Array of constants + * + * @param constantPool Array of constants */ - public LineNumberTable(final int name_index, final int length, final LineNumber[] line_number_table, - final ConstantPool constant_pool) { - super(Const.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); - this.lineNumberTable = line_number_table; + public LineNumberTable(final int nameIndex, final int length, final LineNumber[] lineNumberTable, final ConstantPool constantPool) { + super(Const.ATTR_LINE_NUMBER_TABLE, nameIndex, length, constantPool); + this.lineNumberTable = lineNumberTable != null ? lineNumberTable : LineNumber.EMPTY_ARRAY; + Args.requireU2(this.lineNumberTable.length, "lineNumberTable.length"); } - /** - * Construct object from input stream. - * @param name_index Index of name - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException if an I/O Exception occurs in readUnsignedShort + /* + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. */ - LineNumberTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, (LineNumber[]) null, constant_pool); - final int line_number_table_length = input.readUnsignedShort(); - lineNumberTable = new LineNumber[line_number_table_length]; - for (int i = 0; i < line_number_table_length; i++) { - lineNumberTable[i] = new LineNumber(input); - } + public LineNumberTable(final LineNumberTable c) { + this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLineNumberTable(this); } /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + // TODO could use the lower level constructor and thereby allow + // lineNumberTable to be made final + final LineNumberTable c = (LineNumberTable) clone(); + c.lineNumberTable = new LineNumber[lineNumberTable.length]; + Arrays.setAll(c.lineNumberTable, i -> lineNumberTable[i].copy()); + c.setConstantPool(constantPool); + return c; + } + + /** * Dump line number table attribute to file stream in binary format. * * @param file Output file stream * @throws IOException if an I/O Exception occurs in writeShort */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(lineNumberTable.length); for (final LineNumber lineNumber : lineNumberTable) { @@ -114,97 +132,86 @@ } /** - * @param lineNumberTable the line number entries for this table - */ - public void setLineNumberTable( final LineNumber[] lineNumberTable ) { - this.lineNumberTable = lineNumberTable; - } - - /** - * @return String representation. - */ - @Override - public String toString() { - final StringBuilder buf = new StringBuilder(); - final StringBuilder line = new StringBuilder(); - - for (int i = 0; i < lineNumberTable.length; i++) { - line.append(lineNumberTable[i].toString()); - if (i < lineNumberTable.length - 1) { - line.append(", "); - } - if ((line.length() > MAX_LINE_LENGTH) && (i < lineNumberTable.length - 1)) { - line.append(SecuritySupport.NEWLINE); - buf.append(line); - line.setLength(0); - } - } - buf.append(line); - return buf.toString(); - } - - /** * Map byte code positions to source code lines. * * @param pos byte code offset * @return corresponding line in source code */ - public int getSourceLine( final int pos ) { + public int getSourceLine(final int pos) { int l = 0; int r = lineNumberTable.length - 1; if (r < 0) { return -1; } - int min_index = -1; + int minIndex = -1; int min = -1; - /* Do a binary search since the array is ordered. + /* + * Do a binary search since the array is ordered. */ do { - final int i = (l + r) >>> 1; + final int i = l + r >>> 1; final int j = lineNumberTable[i].getStartPC(); if (j == pos) { return lineNumberTable[i].getLineNumber(); - } else if (pos < j) { + } + if (pos < j) { r = i - 1; } else { l = i + 1; } - /* If exact match can't be found (which is the most common case) - * return the line number that corresponds to the greatest index less - * than pos. + /* + * If exact match can't be found (which is the most common case) return the line number that corresponds to the greatest + * index less than pos. */ if (j < pos && j > min) { min = j; - min_index = i; + minIndex = i; } } while (l <= r); - /* It's possible that we did not find any valid entry for the bytecode - * offset we were looking for. + /* + * It's possible that we did not find any valid entry for the bytecode offset we were looking for. */ - if (min_index < 0) { + if (minIndex < 0) { return -1; } - return lineNumberTable[min_index].getLineNumber(); + return lineNumberTable[minIndex].getLineNumber(); + } + + public int getTableLength() { + return lineNumberTable == null ? 0 : lineNumberTable.length; + } + + @Override + public Iterator iterator() { + return Stream.of(lineNumberTable).iterator(); } /** - * @return deep copy of this attribute + * @param lineNumberTable the line number entries for this table + */ + public void setLineNumberTable(final LineNumber[] lineNumberTable) { + this.lineNumberTable = lineNumberTable; + } + + /** + * @return String representation. */ @Override - public Attribute copy( final ConstantPool _constant_pool ) { - // TODO could use the lower level constructor and thereby allow - // lineNumberTable to be made final - final LineNumberTable c = (LineNumberTable) clone(); - c.lineNumberTable = new LineNumber[lineNumberTable.length]; + public String toString() { + final StringBuilder buf = new StringBuilder(); + final StringBuilder line = new StringBuilder(); for (int i = 0; i < lineNumberTable.length; i++) { - c.lineNumberTable[i] = lineNumberTable[i].copy(); + line.append(lineNumberTable[i].toString()); + if (i < lineNumberTable.length - 1) { + line.append(", "); + } + if (line.length() > MAX_LINE_LENGTH && i < lineNumberTable.length - 1) { + line.append(SecuritySupport.NEWLINE); + buf.append(line); + line.setLength(0); + } } - c.setConstantPool(_constant_pool); - return c; - } - - - public int getTableLength() { - return lineNumberTable == null ? 0 : lineNumberTable.length; + buf.append(line); + return buf.toString(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,119 +24,129 @@ import java.io.DataOutputStream; import java.io.IOException; -import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class represents a local variable within a method. It contains its - * scope, name, signature and index on the method's frame. It is used both - * to represent an element of the LocalVariableTable as well as an element - * of the LocalVariableTypeTable. The nomenclature used here may be a bit confusing; - * while the two items have the same layout in a class file, a LocalVariableTable - * attribute contains a descriptor_index, not a signatureIndex. The + * This class represents a local variable within a method. It contains its scope, name, signature and index on the + * method's frame. It is used both to represent an element of the LocalVariableTable as well as an element of the + * LocalVariableTypeTable. The nomenclature used here may be a bit confusing; while the two items have the same layout + * in a class file, a LocalVariableTable attribute contains a descriptor_index, not a signatureIndex. The * LocalVariableTypeTable attribute does have a signatureIndex. + * * @see com.sun.org.apache.bcel.internal.classfile.Utility for more details on the difference. * - * @see LocalVariableTable - * @see LocalVariableTypeTable - * @LastModified: May 2021 + * @see LocalVariableTable + * @see LocalVariableTypeTable + * @LastModified: Feb 2023 */ public final class LocalVariable implements Cloneable, Node { - private int startPc; // Range in which the variable is valid + static final LocalVariable[] EMPTY_ARRAY = {}; + + /** Range in which the variable is valid. */ + private int startPc; + private int length; - private int nameIndex; // Index in constant pool of variable name - // Technically, a decscriptor_index for a local variable table entry - // and a signatureIndex for a local variable type table entry. - private int signatureIndex; // Index of variable signature - private int index; /* Variable is index'th local variable on - * this method's frame. - */ - private ConstantPool constantPool; - private int origIndex; // never changes; used to match up with LocalVariableTypeTable entries + /** Index in constant pool of variable name. */ + private int nameIndex; /** - * Initializes from another LocalVariable. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - * - * @param localVariable Another LocalVariable. + * Technically, a decscriptor_index for a local variable table entry and a signatureIndex for a local variable type table entry. Index of variable signature */ - public LocalVariable(final LocalVariable localVariable) { - this(localVariable.getStartPC(), localVariable.getLength(), localVariable.getNameIndex(), - localVariable.getSignatureIndex(), localVariable.getIndex(), localVariable.getConstantPool()); - this.origIndex = localVariable.getOrigIndex(); - } + private int signatureIndex; + + /* + * Variable is index'th local variable on this method's frame. + */ + private int index; + + private ConstantPool constantPool; + + /** Never changes; used to match up with LocalVariableTypeTable entries. */ + private final int origIndex; /** * Constructs object from file stream. + * * @param file Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - LocalVariable(final DataInput file, final ConstantPool constant_pool) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file - .readUnsignedShort(), file.readUnsignedShort(), constant_pool); + LocalVariable(final DataInput file, final ConstantPool constantPool) throws IOException { + this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), constantPool); } - /** * @param startPc Range in which the variable * @param length ... is valid * @param nameIndex Index in constant pool of variable name * @param signatureIndex Index of variable's signature - * @param index Variable is `index'th local variable on the method's frame + * @param index Variable is 'index'th local variable on the method's frame * @param constantPool Array of constants */ - public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index, - final ConstantPool constantPool) { - this.startPc = startPc; - this.length = length; - this.nameIndex = nameIndex; - this.signatureIndex = signatureIndex; - this.index = index; - this.constantPool = constantPool; - this.origIndex = index; + public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index, final ConstantPool constantPool) { + this(startPc, length, nameIndex, signatureIndex, index, constantPool, index); } - /** * @param startPc Range in which the variable * @param length ... is valid * @param nameIndex Index in constant pool of variable name * @param signatureIndex Index of variable's signature - * @param index Variable is `index'th local variable on the method's frame + * @param index Variable is 'index'th local variable on the method's frame * @param constantPool Array of constants - * @param origIndex Variable is `index'th local variable on the method's frame prior to any changes + * @param origIndex Variable is 'index'th local variable on the method's frame prior to any changes */ - public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index, - final ConstantPool constantPool, final int origIndex) { - this.startPc = startPc; - this.length = length; - this.nameIndex = nameIndex; - this.signatureIndex = signatureIndex; - this.index = index; + public LocalVariable(final int startPc, final int length, final int nameIndex, final int signatureIndex, final int index, final ConstantPool constantPool, + final int origIndex) { + this.startPc = Args.requireU2(startPc, "startPc"); + this.length = Args.requireU2(length, "length"); + this.nameIndex = Args.requireU2(nameIndex, "nameIndex"); + this.signatureIndex = Args.requireU2(signatureIndex, "signatureIndex"); + this.index = Args.requireU2(index, "index"); + this.origIndex = Args.requireU2(origIndex, "origIndex"); this.constantPool = constantPool; - this.origIndex = origIndex; } + /** + * Initializes from another LocalVariable. Note that both objects use the same references (shallow copy). Use copy() for + * a physical copy. + * + * @param localVariable Another LocalVariable. + */ + public LocalVariable(final LocalVariable localVariable) { + this(localVariable.getStartPC(), localVariable.getLength(), localVariable.getNameIndex(), localVariable.getSignatureIndex(), localVariable.getIndex(), + localVariable.getConstantPool()); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLocalVariable(this); } + /** + * @return deep copy of this object + */ + public LocalVariable copy() { + try { + return (LocalVariable) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } /** * Dumps local variable to file stream in binary format. * * @param dataOutputStream Output file stream - * @exception IOException if an I/O error occurs. + * @throws IOException if an I/O error occurs. * @see java.io.FilterOutputStream#out */ public void dump(final DataOutputStream dataOutputStream) throws IOException { @@ -154,6 +164,12 @@ return constantPool; } + /** + * @return index of register where variable is stored + */ + public int getIndex() { + return index; + } /** * @return Variable is valid within getStartPC() .. getStartPC()+getLength() @@ -162,17 +178,13 @@ return length; } - /** * @return Variable name. */ public String getName() { - ConstantUtf8 c; - c = (ConstantUtf8) constantPool.getConstant(nameIndex, Const.CONSTANT_Utf8); - return c.getBytes(); + return constantPool.getConstantUtf8(nameIndex).getBytes(); } - /** * @return Index in constant pool of variable name. */ @@ -180,17 +192,20 @@ return nameIndex; } + /** + * @return index of register where variable was originally stored + */ + public int getOrigIndex() { + return origIndex; + } /** * @return Signature. */ public String getSignature() { - ConstantUtf8 c; - c = (ConstantUtf8) constantPool.getConstant(signatureIndex, Const.CONSTANT_Utf8); - return c.getBytes(); + return constantPool.getConstantUtf8(signatureIndex).getBytes(); } - /** * @return Index in constant pool of variable signature. */ @@ -198,23 +213,6 @@ return signatureIndex; } - - /** - * @return index of register where variable is stored - */ - public int getIndex() { - return index; - } - - - /** - * @return index of register where variable was originally stored - */ - public int getOrigIndex() { - return origIndex; - } - - /** * @return Start of range where the variable is valid */ @@ -222,67 +220,48 @@ return startPc; } - - /* - * Helper method shared with LocalVariableTypeTable - */ - String toStringShared( final boolean typeTable ) { - final String name = getName(); - final String signature = Utility.signatureToString(getSignature(), false); - final String label = "LocalVariable" + (typeTable ? "Types" : "" ); - return label + "(startPc = " + startPc + ", length = " + length + ", index = " - + index + ":" + signature + " " + name + ")"; - } - - /** * @param constantPool Constant pool to be used for this object. */ - public void setConstantPool( final ConstantPool constantPool ) { + public void setConstantPool(final ConstantPool constantPool) { this.constantPool = constantPool; } + /** + * @param index the index in the local variable table of this variable + */ + public void setIndex(final int index) { // TODO unused + this.index = index; + } /** * @param length the length of this local variable */ - public void setLength( final int length ) { + public void setLength(final int length) { this.length = length; } - /** * @param nameIndex the index into the constant pool for the name of this variable */ - public void setNameIndex( final int nameIndex ) { // TODO unused + public void setNameIndex(final int nameIndex) { // TODO unused this.nameIndex = nameIndex; } - /** * @param signatureIndex the index into the constant pool for the signature of this variable */ - public void setSignatureIndex( final int signatureIndex ) { // TODO unused + public void setSignatureIndex(final int signatureIndex) { // TODO unused this.signatureIndex = signatureIndex; } - - /** - * @param index the index in the local variable table of this variable - */ - public void setIndex( final int index ) { // TODO unused - this.index = index; - } - - /** * @param startPc Specify range where the local variable is valid. */ - public void setStartPC( final int startPc ) { // TODO unused + public void setStartPC(final int startPc) { // TODO unused this.startPc = startPc; } - /** * @return string representation. */ @@ -291,16 +270,13 @@ return toStringShared(false); } - - /** - * @return deep copy of this object + /* + * Helper method shared with LocalVariableTypeTable */ - public LocalVariable copy() { - try { - return (LocalVariable) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; + String toStringShared(final boolean typeTable) { + final String name = getName(); + final String signature = Utility.signatureToString(getSignature(), false); + final String label = "LocalVariable" + (typeTable ? "Types" : ""); + return label + "(startPc = " + startPc + ", length = " + length + ", index = " + index + ":" + signature + " " + name + ")"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,83 +24,95 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.stream.Stream; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class represents colection of local variables in a - * method. This attribute is contained in the Code attribute. + * This class represents colection of local variables in a method. This attribute is contained in the Code + * attribute. * - * @see Code + * @see Code * @see LocalVariable */ -public class LocalVariableTable extends Attribute { +public class LocalVariableTable extends Attribute implements Iterable { private LocalVariable[] localVariableTable; // variables - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Construct object from input stream. + * + * @param nameIndex Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - public LocalVariableTable(final LocalVariableTable c) { - this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); + LocalVariableTable(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (LocalVariable[]) null, constantPool); + final int localVariableTableLength = input.readUnsignedShort(); + localVariableTable = new LocalVariable[localVariableTableLength]; + for (int i = 0; i < localVariableTableLength; i++) { + localVariableTable[i] = new LocalVariable(input, constantPool); + } } - /** - * @param nameIndex Index in constant pool to `LocalVariableTable' + * @param nameIndex Index in constant pool to 'LocalVariableTable' * @param length Content length in bytes * @param localVariableTable Table of local variables * @param constantPool Array of constants */ - public LocalVariableTable(final int nameIndex, final int length, final LocalVariable[] localVariableTable, - final ConstantPool constantPool) { + public LocalVariableTable(final int nameIndex, final int length, final LocalVariable[] localVariableTable, final ConstantPool constantPool) { super(Const.ATTR_LOCAL_VARIABLE_TABLE, nameIndex, length, constantPool); - this.localVariableTable = localVariableTable; + this.localVariableTable = localVariableTable != null ? localVariableTable : LocalVariable.EMPTY_ARRAY; + Args.requireU2(this.localVariableTable.length, "localVariableTable.length"); } - /** - * Construct object from input stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. */ - LocalVariableTable(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, (LocalVariable[]) null, constant_pool); - final int local_variable_table_length = input.readUnsignedShort(); - localVariableTable = new LocalVariable[local_variable_table_length]; - for (int i = 0; i < local_variable_table_length; i++) { - localVariableTable[i] = new LocalVariable(input, constant_pool); - } + public LocalVariableTable(final LocalVariableTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLocalVariableTable(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final LocalVariableTable c = (LocalVariableTable) clone(); + c.localVariableTable = new LocalVariable[localVariableTable.length]; + Arrays.setAll(c.localVariableTable, i -> localVariableTable[i].copy()); + c.setConstantPool(constantPool); + return c; + } /** * Dump local variable table attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public final void dump( final DataOutputStream file ) throws IOException { + public final void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(localVariableTable.length); for (final LocalVariable variable : localVariableTable) { @@ -108,26 +120,17 @@ } } - - /** - * @return Array of local variables of method. - */ - public final LocalVariable[] getLocalVariableTable() { - return localVariableTable; - } - - /** * * @param index the variable slot * * @return the first LocalVariable that matches the slot or null if not found * - * @deprecated since 5.2 because multiple variables can share the - * same slot, use getLocalVariable(int index, int pc) instead. + * @deprecated since 5.2 because multiple variables can share the same slot, use getLocalVariable(int index, int pc) + * instead. */ @java.lang.Deprecated - public final LocalVariable getLocalVariable( final int index ) { + public final LocalVariable getLocalVariable(final int index) { for (final LocalVariable variable : localVariableTable) { if (variable.getIndex() == index) { return variable; @@ -136,7 +139,6 @@ return null; } - /** * * @param index the variable slot @@ -144,12 +146,12 @@ * * @return the LocalVariable that matches or null if not found */ - public final LocalVariable getLocalVariable( final int index, final int pc ) { + public final LocalVariable getLocalVariable(final int index, final int pc) { for (final LocalVariable variable : localVariableTable) { if (variable.getIndex() == index) { - final int start_pc = variable.getStartPC(); - final int end_pc = start_pc + variable.getLength(); - if ((pc >= start_pc) && (pc <= end_pc)) { + final int startPc = variable.getStartPC(); + final int endPc = startPc + variable.getLength(); + if (pc >= startPc && pc <= endPc) { return variable; } } @@ -157,11 +159,25 @@ return null; } + /** + * @return Array of local variables of method. + */ + public final LocalVariable[] getLocalVariableTable() { + return localVariableTable; + } + + public final int getTableLength() { + return localVariableTable == null ? 0 : localVariableTable.length; + } - public final void setLocalVariableTable( final LocalVariable[] local_variable_table ) { - this.localVariableTable = local_variable_table; + @Override + public Iterator iterator() { + return Stream.of(localVariableTable).iterator(); } + public final void setLocalVariableTable(final LocalVariable[] localVariableTable) { + this.localVariableTable = localVariableTable; + } /** * @return String representation. @@ -177,24 +193,4 @@ } return buf.toString(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final LocalVariableTable c = (LocalVariableTable) clone(); - c.localVariableTable = new LocalVariable[localVariableTable.length]; - for (int i = 0; i < localVariableTable.length; i++) { - c.localVariableTable[i] = localVariableTable[i].copy(); - } - c.setConstantPool(_constant_pool); - return c; - } - - - public final int getTableLength() { - return localVariableTable == null ? 0 : localVariableTable.length; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTypeTable.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,12 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.stream.Stream; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; // The new table is used when generic types are about... @@ -57,35 +61,49 @@ /** * @since 6.0 */ -public class LocalVariableTypeTable extends Attribute { +public class LocalVariableTypeTable extends Attribute implements Iterable { - private LocalVariable[] localVariableTypeTable; // variables - - public LocalVariableTypeTable(final LocalVariableTypeTable c) { - this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool()); - } - - public LocalVariableTypeTable(final int name_index, final int length, final LocalVariable[] local_variable_table, final ConstantPool constant_pool) { - super(Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE, name_index, length, constant_pool); - this.localVariableTypeTable = local_variable_table; - } + private LocalVariable[] localVariableTypeTable; // variables LocalVariableTypeTable(final int nameIdx, final int len, final DataInput input, final ConstantPool cpool) throws IOException { this(nameIdx, len, (LocalVariable[]) null, cpool); - final int local_variable_type_table_length = input.readUnsignedShort(); - localVariableTypeTable = new LocalVariable[local_variable_type_table_length]; + final int localVariableTypeTableLength = input.readUnsignedShort(); + localVariableTypeTable = new LocalVariable[localVariableTypeTableLength]; - for (int i = 0; i < local_variable_type_table_length; i++) { + for (int i = 0; i < localVariableTypeTableLength; i++) { localVariableTypeTable[i] = new LocalVariable(input, cpool); } } + public LocalVariableTypeTable(final int nameIndex, final int length, final LocalVariable[] localVariableTypeTable, final ConstantPool constantPool) { + super(Const.ATTR_LOCAL_VARIABLE_TYPE_TABLE, nameIndex, length, constantPool); + this.localVariableTypeTable = localVariableTypeTable != null ? localVariableTypeTable : LocalVariable.EMPTY_ARRAY; + Args.requireU2(this.localVariableTypeTable.length, "localVariableTypeTable.length"); + } + + public LocalVariableTypeTable(final LocalVariableTypeTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTypeTable(), c.getConstantPool()); + } + @Override public void accept(final Visitor v) { v.visitLocalVariableTypeTable(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final LocalVariableTypeTable c = (LocalVariableTypeTable) clone(); + + c.localVariableTypeTable = new LocalVariable[localVariableTypeTable.length]; + Arrays.setAll(c.localVariableTypeTable, i -> localVariableTypeTable[i].copy()); + c.setConstantPool(constantPool); + return c; + } + @Override public final void dump(final DataOutputStream file) throws IOException { super.dump(file); @@ -95,10 +113,6 @@ } } - public final LocalVariable[] getLocalVariableTypeTable() { - return localVariableTypeTable; - } - public final LocalVariable getLocalVariable(final int index) { for (final LocalVariable variable : localVariableTypeTable) { if (variable.getIndex() == index) { @@ -109,8 +123,21 @@ return null; } - public final void setLocalVariableTable(final LocalVariable[] local_variable_table) { - this.localVariableTypeTable = local_variable_table; + public final LocalVariable[] getLocalVariableTypeTable() { + return localVariableTypeTable; + } + + public final int getTableLength() { + return localVariableTypeTable == null ? 0 : localVariableTypeTable.length; + } + + @Override + public Iterator iterator() { + return Stream.of(localVariableTypeTable).iterator(); + } + + public final void setLocalVariableTable(final LocalVariable[] localVariableTable) { + this.localVariableTypeTable = localVariableTable; } /** @@ -130,24 +157,4 @@ return buf.toString(); } - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy(final ConstantPool constant_pool) { - final LocalVariableTypeTable c = (LocalVariableTypeTable) clone(); - - c.localVariableTypeTable = new LocalVariable[localVariableTypeTable.length]; - for (int i = 0; i < localVariableTypeTable.length; i++) { - c.localVariableTypeTable[i] = localVariableTypeTable[i].copy(); - } - - c.setConstantPool(constant_pool); - return c; - } - - public final int getTableLength() { - return localVariableTypeTable == null ? 0 : localVariableTypeTable.length; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,93 +24,133 @@ import java.io.IOException; import java.util.Objects; -import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.generic.Type; import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * This class represents the method info structure, i.e., the representation - * for a method in the class. See JVM specification for details. - * A method has access flags, a name, a signature and a number of attributes. - * + * This class represents the method info structure, i.e., the representation for a method in the class. See JVM + * specification for details. A method has access flags, a name, a signature and a number of attributes. */ public final class Method extends FieldOrMethod { + /** + * Empty array constant. + * + * @since 6.6.0 + */ + public static final Method[] EMPTY_ARRAY = {}; + private static BCELComparator bcelComparator = new BCELComparator() { @Override - public boolean equals( final Object o1, final Object o2 ) { + public boolean equals(final Object o1, final Object o2) { final Method THIS = (Method) o1; final Method THAT = (Method) o2; - return Objects.equals(THIS.getName(), THAT.getName()) - && Objects.equals(THIS.getSignature(), THAT.getSignature()); + return Objects.equals(THIS.getName(), THAT.getName()) && Objects.equals(THIS.getSignature(), THAT.getSignature()); } - @Override - public int hashCode( final Object o ) { + public int hashCode(final Object o) { final Method THIS = (Method) o; return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); } }; - // annotations defined on the parameters of a method - private ParameterAnnotationEntry[] parameterAnnotationEntries; + /** + * Empty array. + */ + static final Method[] EMPTY_METHOD_ARRAY = {}; /** - * Empty constructor, all attributes have to be defined via `setXXX' - * methods. Use at your own risk. + * @return Comparison strategy object */ - public Method() { + public static BCELComparator getComparator() { + return bcelComparator; } - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. + * @param comparator Comparison strategy object */ - public Method(final Method c) { - super(c); + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; } + // annotations defined on the parameters of a method + private ParameterAnnotationEntry[] parameterAnnotationEntries; + + /** + * Empty constructor, all attributes have to be defined via 'setXXX' methods. Use at your own risk. + */ + public Method() { + } /** * Construct object from file stream. + * * @param file Input stream - * @throws IOException - * @throws ClassFormatException + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ - Method(final DataInput file, final ConstantPool constant_pool) throws IOException, - ClassFormatException { - super(file, constant_pool); + Method(final DataInput file, final ConstantPool constantPool) throws IOException, ClassFormatException { + super(file, constantPool); } - /** - * @param access_flags Access rights of method - * @param name_index Points to field name in constant pool - * @param signature_index Points to encoded signature + * @param accessFlags Access rights of method + * @param nameIndex Points to field name in constant pool + * @param signatureIndex Points to encoded signature * @param attributes Collection of attributes - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public Method(final int access_flags, final int name_index, final int signature_index, final Attribute[] attributes, - final ConstantPool constant_pool) { - super(access_flags, name_index, signature_index, attributes, constant_pool); + public Method(final int accessFlags, final int nameIndex, final int signatureIndex, final Attribute[] attributes, final ConstantPool constantPool) { + super(accessFlags, nameIndex, signatureIndex, attributes, constantPool); } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. + */ + public Method(final Method c) { + super(c); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitMethod(this); } + /** + * @return deep copy of this method + */ + public Method copy(final ConstantPool constantPool) { + return (Method) copy_(constantPool); + } + + /** + * Return value as defined by given BCELComparator strategy. By default two method objects are said to be equal when + * their names and signatures are equal. + * + * @see Object#equals(Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } + + /** + * @return array of method argument types + */ + public Type[] getArgumentTypes() { + return Type.getArgumentTypes(getSignature()); + } /** * @return Code attribute of method, if any @@ -124,10 +164,9 @@ return null; } - /** - * @return ExceptionTable attribute of method, if any, i.e., list all - * exceptions the method may throw not exception handlers! + * @return ExceptionTable attribute of method, if any, i.e., list all exceptions the method may throw not exception + * handlers! */ public ExceptionTable getExceptionTable() { for (final Attribute attribute : super.getAttributes()) { @@ -138,34 +177,60 @@ return null; } - - /** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded - * to the Code atribute. + /** + * @return LineNumberTable of code attribute if any, i.e. the call is forwarded to the Code atribute. */ - public LocalVariableTable getLocalVariableTable() { + public LineNumberTable getLineNumberTable() { final Code code = getCode(); if (code == null) { return null; } - return code.getLocalVariableTable(); + return code.getLineNumberTable(); } - - /** @return LineNumberTable of code attribute if any, i.e. the call is forwarded - * to the Code atribute. + /** + * @return LocalVariableTable of code attribute if any, i.e. the call is forwarded to the Code atribute. */ - public LineNumberTable getLineNumberTable() { + public LocalVariableTable getLocalVariableTable() { final Code code = getCode(); if (code == null) { return null; } - return code.getLineNumberTable(); + return code.getLocalVariableTable(); + } + + /** + * @return Annotations on the parameters of a method + * @since 6.0 + */ + public ParameterAnnotationEntry[] getParameterAnnotationEntries() { + if (parameterAnnotationEntries == null) { + parameterAnnotationEntries = ParameterAnnotationEntry.createParameterAnnotationEntries(getAttributes()); + } + return parameterAnnotationEntries; + } + + /** + * @return return type of method + */ + public Type getReturnType() { + return Type.getReturnType(getSignature()); } + /** + * Return value as defined by given BCELComparator strategy. By default return the hashcode of the method's name XOR + * signature. + * + * @see Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); + } /** - * Return string representation close to declaration format, - * `public static void main(String[] args) throws IOException', e.g. + * Return string representation close to declaration format, 'public static void main(String[] args) throws + * IOException', e.g. * * @return String representation of the method. */ @@ -173,15 +238,14 @@ public String toString() { final String access = Utility.accessToString(super.getAccessFlags()); // Get name and signature from constant pool - ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(super.getSignatureIndex(), Const.CONSTANT_Utf8); + ConstantUtf8 c = super.getConstantPool().getConstantUtf8(super.getSignatureIndex()); String signature = c.getBytes(); - c = (ConstantUtf8) super.getConstantPool().getConstant(super.getNameIndex(), Const.CONSTANT_Utf8); + c = super.getConstantPool().getConstantUtf8(super.getNameIndex()); final String name = c.getBytes(); - signature = Utility.methodSignatureToString(signature, name, access, true, - getLocalVariableTable()); + signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable()); final StringBuilder buf = new StringBuilder(signature); for (final Attribute attribute : super.getAttributes()) { - if (!((attribute instanceof Code) || (attribute instanceof ExceptionTable))) { + if (!(attribute instanceof Code || attribute instanceof ExceptionTable)) { buf.append(" [").append(attribute).append("]"); } } @@ -194,80 +258,4 @@ } return buf.toString(); } - - - /** - * @return deep copy of this method - */ - public Method copy( final ConstantPool _constant_pool ) { - return (Method) copy_(_constant_pool); - } - - - /** - * @return return type of method - */ - public Type getReturnType() { - return Type.getReturnType(getSignature()); - } - - - /** - * @return array of method argument types - */ - public Type[] getArgumentTypes() { - return Type.getArgumentTypes(getSignature()); - } - - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return bcelComparator; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two method objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals( final Object obj ) { - return bcelComparator.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the method's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return bcelComparator.hashCode(this); - } - - /** - * @return Annotations on the parameters of a method - * @since 6.0 - */ - public ParameterAnnotationEntry[] getParameterAnnotationEntries() { - if (parameterAnnotationEntries == null) { - parameterAnnotationEntries = ParameterAnnotationEntry.createParameterAnnotationEntries(getAttributes()); - } - return parameterAnnotationEntries; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameter.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,11 +30,11 @@ /** * Entry of the parameters table. * - * @see - * The class File Format : The MethodParameters Attribute + * @see The class File Format : + * The MethodParameters Attribute * @since 6.0 */ -public class MethodParameter implements Cloneable { +public class MethodParameter implements Cloneable, Node { /** Index of the CONSTANT_Utf8_info structure in the constant_pool table representing the name of the parameter */ private int nameIndex; @@ -49,76 +49,77 @@ * Construct object from input stream. * * @param input Input stream - * @throws java.io.IOException - * @throws ClassFormatException + * @throws IOException if an I/O error occurs. + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ MethodParameter(final DataInput input) throws IOException { nameIndex = input.readUnsignedShort(); accessFlags = input.readUnsignedShort(); } - public int getNameIndex() { - return nameIndex; + @Override + public void accept(final Visitor v) { + v.visitMethodParameter(this); } - public void setNameIndex(final int name_index) { - this.nameIndex = name_index; + /** + * @return deep copy of this object + */ + public MethodParameter copy() { + try { + return (MethodParameter) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; } /** - * Returns the name of the parameter. + * Dump object to file stream on binary format. + * + * @param file Output file stream + * @throws IOException if an I/O error occurs. */ - public String getParameterName(final ConstantPool constant_pool) { - if (nameIndex == 0) { - return null; - } - return ((ConstantUtf8) constant_pool.getConstant(nameIndex, Const.CONSTANT_Utf8)).getBytes(); - } + public final void dump(final DataOutputStream file) throws IOException { + file.writeShort(nameIndex); + file.writeShort(accessFlags); + } public int getAccessFlags() { return accessFlags; } - public void setAccessFlags(final int access_flags) { - this.accessFlags = access_flags; + public int getNameIndex() { + return nameIndex; } - public boolean isFinal() { - return (accessFlags & Const.ACC_FINAL) != 0; + /** + * Returns the name of the parameter. + */ + public String getParameterName(final ConstantPool constantPool) { + if (nameIndex == 0) { + return null; + } + return constantPool.getConstantUtf8(nameIndex).getBytes(); } - public boolean isSynthetic() { - return (accessFlags & Const.ACC_SYNTHETIC) != 0; + public boolean isFinal() { + return (accessFlags & Const.ACC_FINAL) != 0; } public boolean isMandated() { return (accessFlags & Const.ACC_MANDATED) != 0; } - public void accept(final Visitor v) { - v.visitMethodParameter(this); + public boolean isSynthetic() { + return (accessFlags & Const.ACC_SYNTHETIC) != 0; } - /** - * Dump object to file stream on binary format. - * - * @param file Output file stream - * @throws IOException - */ - public final void dump(final DataOutputStream file) throws IOException { - file.writeShort(nameIndex); - file.writeShort(accessFlags); + public void setAccessFlags(final int accessFlags) { + this.accessFlags = accessFlags; } - /** - * @return deep copy of this object - */ - public MethodParameter copy() { - try { - return (MethodParameter) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; + public void setNameIndex(final int nameIndex) { + this.nameIndex = nameIndex; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/MethodParameters.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,52 +24,50 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.stream.Stream; import com.sun.org.apache.bcel.internal.Const; /** * This class represents a MethodParameters attribute. * - * @see - * The class File Format : The MethodParameters Attribute + * @see The class File Format : + * The MethodParameters Attribute * @since 6.0 */ -public class MethodParameters extends Attribute { +public class MethodParameters extends Attribute implements Iterable { - private MethodParameter[] parameters = new MethodParameter[0]; + /** + * Empty array. + */ + private static final MethodParameter[] EMPTY_METHOD_PARAMETER_ARRAY = {}; + + private MethodParameter[] parameters = EMPTY_METHOD_PARAMETER_ARRAY; - MethodParameters(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - super(Const.ATTR_METHOD_PARAMETERS, name_index, length, constant_pool); + MethodParameters(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + super(Const.ATTR_METHOD_PARAMETERS, nameIndex, length, constantPool); - final int parameters_count = input.readUnsignedByte(); - parameters = new MethodParameter[parameters_count]; - for (int i = 0; i < parameters_count; i++) { + final int parameterCount = input.readUnsignedByte(); + parameters = new MethodParameter[parameterCount]; + for (int i = 0; i < parameterCount; i++) { parameters[i] = new MethodParameter(input); } } - public MethodParameter[] getParameters() { - return parameters; - } - - public void setParameters(final MethodParameter[] parameters) { - this.parameters = parameters; - } - @Override public void accept(final Visitor v) { v.visitMethodParameters(this); } @Override - public Attribute copy(final ConstantPool _constant_pool) { + public Attribute copy(final ConstantPool constantPool) { final MethodParameters c = (MethodParameters) clone(); c.parameters = new MethodParameter[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - c.parameters[i] = parameters[i].copy(); - } - c.setConstantPool(_constant_pool); + Arrays.setAll(c.parameters, i -> parameters[i].copy()); + c.setConstantPool(constantPool); return c; } @@ -77,14 +75,27 @@ * Dump method parameters attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump(final DataOutputStream file) throws IOException { - super.dump(file); - file.writeByte(parameters.length); + public void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeByte(parameters.length); for (final MethodParameter parameter : parameters) { parameter.dump(file); } } + + public MethodParameter[] getParameters() { + return parameters; + } + + @Override + public Iterator iterator() { + return Stream.of(parameters).iterator(); + } + + public void setParameters(final MethodParameter[] parameters) { + this.parameters = parameters; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleExports.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,19 +28,18 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents an entry in the exports table of the Module attribute. - * Each entry describes a package which may open the parent module. + * This class represents an entry in the exports table of the Module attribute. Each entry describes a package which may + * open the parent module. * - * @see Module + * @see Module * @since 6.4.0 */ public final class ModuleExports implements Cloneable, Node { - private final int exportsIndex; // points to CONSTANT_Package_info + private final int exportsIndex; // points to CONSTANT_Package_info private final int exportsFlags; private final int exportsToCount; - private final int[] exportsToIndex; // points to CONSTANT_Module_info - + private final int[] exportsToIndex; // points to CONSTANT_Module_info /** * Construct object from file stream. @@ -58,28 +57,38 @@ } } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModuleExports(this); } // TODO add more getters and setters? /** + * @return deep copy of this object + */ + public ModuleExports copy() { + try { + return (ModuleExports) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } + + /** * Dump table entry to file stream in binary format. * * @param file Output file stream * @throws IOException if an I/O Exception occurs in writeShort */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(exportsIndex); file.writeShort(exportsFlags); file.writeShort(exportsToCount); @@ -88,7 +97,6 @@ } } - /** * @return String representation */ @@ -97,33 +105,19 @@ return "exports(" + exportsIndex + ", " + exportsFlags + ", " + exportsToCount + ", ...)"; } - /** * @return Resolved string representation */ - public String toString( final ConstantPool constant_pool ) { + public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String package_name = constant_pool.constantToString(exportsIndex, Const.CONSTANT_Package); - buf.append(Utility.compactClassName(package_name, false)); + final String packageName = constantPool.constantToString(exportsIndex, Const.CONSTANT_Package); + buf.append(Utility.compactClassName(packageName, false)); buf.append(", ").append(String.format("%04x", exportsFlags)); buf.append(", to(").append(exportsToCount).append("):\n"); for (final int index : exportsToIndex) { - final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module); - buf.append(" ").append(Utility.compactClassName(module_name, false)).append("\n"); - } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this object - */ - public ModuleExports copy() { - try { - return (ModuleExports) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? + final String moduleName = constantPool.getConstantString(index, Const.CONSTANT_Module); + buf.append(" ").append(Utility.compactClassName(moduleName, false)).append("\n"); } - return null; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Module.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,19 +24,26 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from Attribute and represents the list of - * modules required, exported, opened or provided by a module. - * There may be at most one Module attribute in a ClassFile structure. + * This class is derived from Attribute and represents the list of modules required, exported, opened or + * provided by a module. There may be at most one Module attribute in a ClassFile structure. * - * @see Attribute + * @see Attribute * @since 6.4.0 */ public final class Module extends Attribute { + /** + * The module file name extension. + * + * @since 6.7.0 + */ + public static final String EXTENSION = ".jmod"; + private final int moduleNameIndex; private final int moduleFlags; private final int moduleVersionIndex; @@ -50,34 +57,35 @@ /** * Construct object from input stream. - * @param name_index Index in constant pool + * + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - Module(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - super(Const.ATTR_MODULE, name_index, length, constant_pool); + Module(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + super(Const.ATTR_MODULE, nameIndex, length, constantPool); moduleNameIndex = input.readUnsignedShort(); moduleFlags = input.readUnsignedShort(); moduleVersionIndex = input.readUnsignedShort(); - final int requires_count = input.readUnsignedShort(); - requiresTable = new ModuleRequires[requires_count]; - for (int i = 0; i < requires_count; i++) { + final int requiresCount = input.readUnsignedShort(); + requiresTable = new ModuleRequires[requiresCount]; + for (int i = 0; i < requiresCount; i++) { requiresTable[i] = new ModuleRequires(input); } - final int exports_count = input.readUnsignedShort(); - exportsTable = new ModuleExports[exports_count]; - for (int i = 0; i < exports_count; i++) { + final int exportsCount = input.readUnsignedShort(); + exportsTable = new ModuleExports[exportsCount]; + for (int i = 0; i < exportsCount; i++) { exportsTable[i] = new ModuleExports(input); } - final int opens_count = input.readUnsignedShort(); - opensTable = new ModuleOpens[opens_count]; - for (int i = 0; i < opens_count; i++) { + final int opensCount = input.readUnsignedShort(); + opensTable = new ModuleOpens[opensCount]; + for (int i = 0; i < opensCount; i++) { opensTable[i] = new ModuleOpens(input); } @@ -87,72 +95,57 @@ usesIndex[i] = input.readUnsignedShort(); } - final int provides_count = input.readUnsignedShort(); - providesTable = new ModuleProvides[provides_count]; - for (int i = 0; i < provides_count; i++) { + final int providesCount = input.readUnsignedShort(); + providesTable = new ModuleProvides[providesCount]; + for (int i = 0; i < providesCount; i++) { providesTable[i] = new ModuleProvides(input); } } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModule(this); } // TODO add more getters and setters? /** - * @return table of required modules - * @see ModuleRequires + * @return deep copy of this attribute */ - public ModuleRequires[] getRequiresTable() { - return requiresTable; - } - + @Override + public Attribute copy(final ConstantPool constantPool) { + final Module c = (Module) clone(); - /** - * @return table of exported interfaces - * @see ModuleExports - */ - public ModuleExports[] getExportsTable() { - return exportsTable; - } + c.requiresTable = new ModuleRequires[requiresTable.length]; + Arrays.setAll(c.requiresTable, i -> requiresTable[i].copy()); + c.exportsTable = new ModuleExports[exportsTable.length]; + Arrays.setAll(c.exportsTable, i -> exportsTable[i].copy()); - /** - * @return table of provided interfaces - * @see ModuleOpens - */ - public ModuleOpens[] getOpensTable() { - return opensTable; - } + c.opensTable = new ModuleOpens[opensTable.length]; + Arrays.setAll(c.opensTable, i -> opensTable[i].copy()); + c.providesTable = new ModuleProvides[providesTable.length]; + Arrays.setAll(c.providesTable, i -> providesTable[i].copy()); - /** - * @return table of provided interfaces - * @see ModuleProvides - */ - public ModuleProvides[] getProvidesTable() { - return providesTable; + c.setConstantPool(constantPool); + return c; } - /** * Dump Module attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(moduleNameIndex); @@ -185,6 +178,37 @@ } } + /** + * @return table of exported interfaces + * @see ModuleExports + */ + public ModuleExports[] getExportsTable() { + return exportsTable; + } + + /** + * @return table of provided interfaces + * @see ModuleOpens + */ + public ModuleOpens[] getOpensTable() { + return opensTable; + } + + /** + * @return table of provided interfaces + * @see ModuleProvides + */ + public ModuleProvides[] getProvidesTable() { + return providesTable; + } + + /** + * @return table of required modules + * @see ModuleRequires + */ + public ModuleRequires[] getRequiresTable() { + return requiresTable; + } /** * @return String representation, i.e., a list of packages. @@ -194,10 +218,10 @@ final ConstantPool cp = super.getConstantPool(); final StringBuilder buf = new StringBuilder(); buf.append("Module:\n"); - buf.append(" name: ") .append(cp.getConstantString(moduleNameIndex, Const.CONSTANT_Module).replace('/', '.')).append("\n"); - buf.append(" flags: ") .append(String.format("%04x", moduleFlags)).append("\n"); + buf.append(" name: ").append(Utility.pathToPackage(cp.getConstantString(moduleNameIndex, Const.CONSTANT_Module))).append("\n"); + buf.append(" flags: ").append(String.format("%04x", moduleFlags)).append("\n"); final String version = moduleVersionIndex == 0 ? "0" : cp.getConstantString(moduleVersionIndex, Const.CONSTANT_Utf8); - buf.append(" version: ") .append(version).append("\n"); + buf.append(" version: ").append(version).append("\n"); buf.append(" requires(").append(requiresTable.length).append("):\n"); for (final ModuleRequires module : requiresTable) { @@ -216,8 +240,8 @@ buf.append(" uses(").append(usesIndex.length).append("):\n"); for (final int index : usesIndex) { - final String class_name = cp.getConstantString(index, Const.CONSTANT_Class); - buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n"); + final String className = cp.getConstantString(index, Const.CONSTANT_Class); + buf.append(" ").append(Utility.compactClassName(className, false)).append("\n"); } buf.append(" provides(").append(providesTable.length).append("):\n"); @@ -225,38 +249,6 @@ buf.append(" ").append(module.toString(cp)).append("\n"); } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final Module c = (Module) clone(); - - c.requiresTable = new ModuleRequires[requiresTable.length]; - for (int i = 0; i < requiresTable.length; i++) { - c.requiresTable[i] = requiresTable[i].copy(); - } - - c.exportsTable = new ModuleExports[exportsTable.length]; - for (int i = 0; i < exportsTable.length; i++) { - c.exportsTable[i] = exportsTable[i].copy(); - } - - c.opensTable = new ModuleOpens[opensTable.length]; - for (int i = 0; i < opensTable.length; i++) { - c.opensTable[i] = opensTable[i].copy(); - } - - c.providesTable = new ModuleProvides[providesTable.length]; - for (int i = 0; i < providesTable.length; i++) { - c.providesTable[i] = providesTable[i].copy(); - } - - c.setConstantPool(_constant_pool); - return c; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleMainClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,66 +26,73 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and indicates the main class of a module. - * There may be at most one ModuleMainClass attribute in a ClassFile structure. + * This class is derived from Attribute and indicates the main class of a module. There may be at most one + * ModuleMainClass attribute in a ClassFile structure. * - * @see Attribute + * @see Attribute */ public final class ModuleMainClass extends Attribute { private int mainClassIndex; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Construct object from input stream. + * + * @param nameIndex Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - public ModuleMainClass(final ModuleMainClass c) { - this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool()); + ModuleMainClass(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, 0, constantPool); + mainClassIndex = input.readUnsignedShort(); } - /** - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param mainClassIndex Host class index * @param constantPool Array of constants */ - public ModuleMainClass(final int name_index, final int length, final int mainClassIndex, - final ConstantPool constantPool) { - super(Const.ATTR_NEST_MEMBERS, name_index, length, constantPool); - this.mainClassIndex = mainClassIndex; + public ModuleMainClass(final int nameIndex, final int length, final int mainClassIndex, final ConstantPool constantPool) { + super(Const.ATTR_NEST_MEMBERS, nameIndex, length, constantPool); + this.mainClassIndex = Args.requireU2(mainClassIndex, "mainClassIndex"); } - /** - * Construct object from input stream. - * @param nameIndex Index in constant pool - * @param length Content length in bytes - * @param input Input stream - * @param constantPool Array of constants - * @throws IOException + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. */ - ModuleMainClass(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { - this(nameIndex, length, 0, constantPool); - mainClassIndex = input.readUnsignedShort(); + public ModuleMainClass(final ModuleMainClass c) { + this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool()); } - /** - * Called by objects that are traversing the nodes of the tree implicitly - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. I.e., + * the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModuleMainClass(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final ModuleMainClass c = (ModuleMainClass) clone(); + c.setConstantPool(constantPool); + return c; + } /** * Dump ModuleMainClass attribute to file stream in binary format. @@ -94,12 +101,11 @@ * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(mainClassIndex); } - /** * @return index into constant pool of host class name. */ @@ -107,15 +113,13 @@ return mainClassIndex; } - /** * @param mainClassIndex the host class index */ - public void setHostClassIndex( final int mainClassIndex ) { + public void setHostClassIndex(final int mainClassIndex) { this.mainClassIndex = mainClassIndex; } - /** * @return String representation */ @@ -123,19 +127,8 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append("ModuleMainClass: "); - final String class_name = super.getConstantPool().getConstantString(mainClassIndex, Const.CONSTANT_Class); - buf.append(Utility.compactClassName(class_name, false)); + final String className = super.getConstantPool().getConstantString(mainClassIndex, Const.CONSTANT_Class); + buf.append(Utility.compactClassName(className, false)); return buf.toString(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final ModuleMainClass c = (ModuleMainClass) clone(); - c.setConstantPool(_constant_pool); - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleOpens.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,19 +28,18 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents an entry in the opens table of the Module attribute. - * Each entry describes a package which the parent module opens. + * This class represents an entry in the opens table of the Module attribute. Each entry describes a package which the + * parent module opens. * - * @see Module + * @see Module * @since 6.4.0 */ public final class ModuleOpens implements Cloneable, Node { - private final int opensIndex; // points to CONSTANT_Package_info + private final int opensIndex; // points to CONSTANT_Package_info private final int opensFlags; private final int opensToCount; - private final int[] opensToIndex; // points to CONSTANT_Module_info - + private final int[] opensToIndex; // points to CONSTANT_Module_info /** * Construct object from file stream. @@ -58,28 +57,38 @@ } } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModuleOpens(this); } // TODO add more getters and setters? /** + * @return deep copy of this object + */ + public ModuleOpens copy() { + try { + return (ModuleOpens) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } + + /** * Dump table entry to file stream in binary format. * * @param file Output file stream * @throws IOException if an I/O Exception occurs in writeShort */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(opensIndex); file.writeShort(opensFlags); file.writeShort(opensToCount); @@ -88,7 +97,6 @@ } } - /** * @return String representation */ @@ -97,33 +105,19 @@ return "opens(" + opensIndex + ", " + opensFlags + ", " + opensToCount + ", ...)"; } - /** * @return Resolved string representation */ - public String toString( final ConstantPool constant_pool ) { + public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String package_name = constant_pool.constantToString(opensIndex, Const.CONSTANT_Package); - buf.append(Utility.compactClassName(package_name, false)); + final String packageName = constantPool.constantToString(opensIndex, Const.CONSTANT_Package); + buf.append(Utility.compactClassName(packageName, false)); buf.append(", ").append(String.format("%04x", opensFlags)); buf.append(", to(").append(opensToCount).append("):\n"); for (final int index : opensToIndex) { - final String module_name = constant_pool.getConstantString(index, Const.CONSTANT_Module); - buf.append(" ").append(Utility.compactClassName(module_name, false)).append("\n"); - } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this object - */ - public ModuleOpens copy() { - try { - return (ModuleOpens) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? + final String moduleName = constantPool.getConstantString(index, Const.CONSTANT_Module); + buf.append(" ").append(Utility.compactClassName(moduleName, false)).append("\n"); } - return null; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModulePackages.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,81 +23,94 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and represents the list of packages that are exported or opened by the Module attribute. - * There may be at most one ModulePackages attribute in a ClassFile structure. + * This class is derived from Attribute and represents the list of packages that are exported or opened by the + * Module attribute. There may be at most one ModulePackages attribute in a ClassFile structure. * - * @see Attribute + * @see Attribute + * @LastModified: Feb 2023 */ public final class ModulePackages extends Attribute { private int[] packageIndexTable; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Construct object from input stream. + * + * @param nameIndex Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - public ModulePackages(final ModulePackages c) { - this(c.getNameIndex(), c.getLength(), c.getPackageIndexTable(), c.getConstantPool()); + ModulePackages(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (int[]) null, constantPool); + final int packageCount = input.readUnsignedShort(); + packageIndexTable = new int[packageCount]; + for (int i = 0; i < packageCount; i++) { + packageIndexTable[i] = input.readUnsignedShort(); + } } - /** * @param nameIndex Index in constant pool * @param length Content length in bytes * @param packageIndexTable Table of indices in constant pool * @param constantPool Array of constants */ - public ModulePackages(final int nameIndex, final int length, final int[] packageIndexTable, - final ConstantPool constantPool) { + public ModulePackages(final int nameIndex, final int length, final int[] packageIndexTable, final ConstantPool constantPool) { super(Const.ATTR_MODULE_PACKAGES, nameIndex, length, constantPool); - this.packageIndexTable = packageIndexTable != null ? packageIndexTable : new int[0]; + this.packageIndexTable = packageIndexTable != null ? packageIndexTable : Const.EMPTY_INT_ARRAY; + Args.requireU2(this.packageIndexTable.length, "packageIndexTable.length"); } - /** - * Construct object from input stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. */ - ModulePackages(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, (int[]) null, constant_pool); - final int number_of_packages = input.readUnsignedShort(); - packageIndexTable = new int[number_of_packages]; - for (int i = 0; i < number_of_packages; i++) { - packageIndexTable[i] = input.readUnsignedShort(); - } + public ModulePackages(final ModulePackages c) { + this(c.getNameIndex(), c.getLength(), c.getPackageIndexTable(), c.getConstantPool()); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModulePackages(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final ModulePackages c = (ModulePackages) clone(); + if (packageIndexTable != null) { + c.packageIndexTable = packageIndexTable.clone(); + } + c.setConstantPool(constantPool); + return c; + } /** * Dump ModulePackages attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(packageIndexTable.length); for (final int index : packageIndexTable) { @@ -106,15 +118,6 @@ } } - - /** - * @return array of indices into constant pool of package names. - */ - public int[] getPackageIndexTable() { - return packageIndexTable; - } - - /** * @return Length of package table. */ @@ -122,29 +125,29 @@ return packageIndexTable == null ? 0 : packageIndexTable.length; } + /** + * @return array of indices into constant pool of package names. + */ + public int[] getPackageIndexTable() { + return packageIndexTable; + } /** * @return string array of package names */ public String[] getPackageNames() { final String[] names = new String[packageIndexTable.length]; - for (int i = 0; i < packageIndexTable.length; i++) { - names[i] = super.getConstantPool().getConstantString(packageIndexTable[i], - Const.CONSTANT_Package).replace('/', '.'); - } + Arrays.setAll(names, i -> Utility.pathToPackage(super.getConstantPool().getConstantString(packageIndexTable[i], Const.CONSTANT_Package))); return names; } - /** - * @param packageIndexTable the list of package indexes - * Also redefines number_of_packages according to table length. + * @param packageIndexTable the list of package indexes Also redefines number_of_packages according to table length. */ - public void setPackageIndexTable( final int[] packageIndexTable ) { - this.packageIndexTable = packageIndexTable != null ? packageIndexTable : new int[0]; + public void setPackageIndexTable(final int[] packageIndexTable) { + this.packageIndexTable = packageIndexTable != null ? packageIndexTable : Const.EMPTY_INT_ARRAY; } - /** * @return String representation, i.e., a list of packages. */ @@ -155,25 +158,9 @@ buf.append(packageIndexTable.length); buf.append("):\n"); for (final int index : packageIndexTable) { - final String package_name = super.getConstantPool().getConstantString(index, Const.CONSTANT_Package); - buf.append(" ").append(Utility.compactClassName(package_name, false)).append("\n"); + final String packageName = super.getConstantPool().getConstantString(index, Const.CONSTANT_Package); + buf.append(" ").append(Utility.compactClassName(packageName, false)).append("\n"); } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final ModulePackages c = (ModulePackages) clone(); - if (packageIndexTable != null) { - c.packageIndexTable = new int[packageIndexTable.length]; - System.arraycopy(packageIndexTable, 0, c.packageIndexTable, 0, - packageIndexTable.length); - } - c.setConstantPool(_constant_pool); - return c; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleProvides.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,18 +28,17 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents an entry in the provides table of the Module attribute. - * Each entry describes a service implementation that the parent module provides. + * This class represents an entry in the provides table of the Module attribute. Each entry describes a service + * implementation that the parent module provides. * - * @see Module + * @see Module * @since 6.4.0 */ public final class ModuleProvides implements Cloneable, Node { - private final int providesIndex; // points to CONSTANT_Class_info + private final int providesIndex; // points to CONSTANT_Class_info private final int providesWithCount; - private final int[] providesWithIndex; // points to CONSTANT_Class_info - + private final int[] providesWithIndex; // points to CONSTANT_Class_info /** * Construct object from file stream. @@ -56,28 +55,38 @@ } } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModuleProvides(this); } // TODO add more getters and setters? /** + * @return deep copy of this object + */ + public ModuleProvides copy() { + try { + return (ModuleProvides) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } + + /** * Dump table entry to file stream in binary format. * * @param file Output file stream * @throws IOException if an I/O Exception occurs in writeShort */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(providesIndex); file.writeShort(providesWithCount); for (final int entry : providesWithIndex) { @@ -85,7 +94,6 @@ } } - /** * @return String representation */ @@ -94,32 +102,18 @@ return "provides(" + providesIndex + ", " + providesWithCount + ", ...)"; } - /** * @return Resolved string representation */ - public String toString( final ConstantPool constant_pool ) { + public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String interface_name = constant_pool.constantToString(providesIndex, Const.CONSTANT_Class); - buf.append(Utility.compactClassName(interface_name, false)); + final String interfaceName = constantPool.constantToString(providesIndex, Const.CONSTANT_Class); + buf.append(Utility.compactClassName(interfaceName, false)); buf.append(", with(").append(providesWithCount).append("):\n"); for (final int index : providesWithIndex) { - final String class_name = constant_pool.getConstantString(index, Const.CONSTANT_Class); - buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n"); - } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this object - */ - public ModuleProvides copy() { - try { - return (ModuleProvides) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? + final String className = constantPool.getConstantString(index, Const.CONSTANT_Class); + buf.append(" ").append(Utility.compactClassName(className, false)).append("\n"); } - return null; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ModuleRequires.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,18 +28,17 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents an entry in the requires table of the Module attribute. - * Each entry describes a module on which the parent module depends. + * This class represents an entry in the requires table of the Module attribute. Each entry describes a module on which + * the parent module depends. * - * @see Module + * @see Module * @since 6.4.0 */ public final class ModuleRequires implements Cloneable, Node { - private final int requiresIndex; // points to CONSTANT_Module_info + private final int requiresIndex; // points to CONSTANT_Module_info private final int requiresFlags; - private final int requiresVersionIndex; // either 0 or points to CONSTANT_Utf8_info - + private final int requiresVersionIndex; // either 0 or points to CONSTANT_Utf8_info /** * Construct object from file stream. @@ -53,34 +52,43 @@ requiresVersionIndex = file.readUnsignedShort(); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitModuleRequires(this); } // TODO add more getters and setters? /** + * @return deep copy of this object + */ + public ModuleRequires copy() { + try { + return (ModuleRequires) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; + } + + /** * Dump table entry to file stream in binary format. * * @param file Output file stream * @throws IOException if an I/O Exception occurs in writeShort */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeShort(requiresIndex); file.writeShort(requiresFlags); file.writeShort(requiresVersionIndex); } - /** * @return String representation */ @@ -89,30 +97,16 @@ return "requires(" + requiresIndex + ", " + String.format("%04x", requiresFlags) + ", " + requiresVersionIndex + ")"; } - /** * @return Resolved string representation */ - public String toString( final ConstantPool constant_pool ) { + public String toString(final ConstantPool constantPool) { final StringBuilder buf = new StringBuilder(); - final String module_name = constant_pool.constantToString(requiresIndex, Const.CONSTANT_Module); - buf.append(Utility.compactClassName(module_name, false)); + final String moduleName = constantPool.constantToString(requiresIndex, Const.CONSTANT_Module); + buf.append(Utility.compactClassName(moduleName, false)); buf.append(", ").append(String.format("%04x", requiresFlags)); - final String version = requiresVersionIndex == 0 ? "0" : constant_pool.getConstantString(requiresVersionIndex, Const.CONSTANT_Utf8); + final String version = requiresVersionIndex == 0 ? "0" : constantPool.getConstantString(requiresVersionIndex, Const.CONSTANT_Utf8); buf.append(", ").append(version); return buf.toString(); } - - - /** - * @return deep copy of this object - */ - public ModuleRequires copy() { - try { - return (ModuleRequires) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestHost.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,67 +26,73 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and records the nest host of the nest - * to which the current class or interface claims to belong. - * There may be at most one NestHost attribute in a ClassFile structure. + * This class is derived from Attribute and records the nest host of the nest to which the current class or + * interface claims to belong. There may be at most one NestHost attribute in a ClassFile structure. * - * @see Attribute + * @see Attribute */ public final class NestHost extends Attribute { private int hostClassIndex; - /** - * Initializes from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Constructs object from input stream. + * + * @param nameIndex Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - public NestHost(final NestHost c) { - this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool()); + NestHost(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, 0, constantPool); + hostClassIndex = input.readUnsignedShort(); } - /** * @param nameIndex Index in constant pool * @param length Content length in bytes * @param hostClassIndex Host class index * @param constantPool Array of constants */ - public NestHost(final int nameIndex, final int length, final int hostClassIndex, - final ConstantPool constantPool) { + public NestHost(final int nameIndex, final int length, final int hostClassIndex, final ConstantPool constantPool) { super(Const.ATTR_NEST_MEMBERS, nameIndex, length, constantPool); - this.hostClassIndex = hostClassIndex; + this.hostClassIndex = Args.requireU2(hostClassIndex, "hostClassIndex"); } - /** - * Constructs object from input stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * Initializes from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. */ - NestHost(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, 0, constant_pool); - hostClassIndex = input.readUnsignedShort(); + public NestHost(final NestHost c) { + this(c.getNameIndex(), c.getLength(), c.getHostClassIndex(), c.getConstantPool()); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitNestHost(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final NestHost c = (NestHost) clone(); + c.setConstantPool(constantPool); + return c; + } /** * Dumps NestHost attribute to file stream in binary format. @@ -95,12 +101,11 @@ * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(hostClassIndex); } - /** * @return index into constant pool of host class name. */ @@ -108,15 +113,13 @@ return hostClassIndex; } - /** * @param hostClassIndex the host class index */ - public void setHostClassIndex( final int hostClassIndex ) { + public void setHostClassIndex(final int hostClassIndex) { this.hostClassIndex = hostClassIndex; } - /** * @return String representation */ @@ -124,19 +127,8 @@ public String toString() { final StringBuilder buf = new StringBuilder(); buf.append("NestHost: "); - final String class_name = super.getConstantPool().getConstantString(hostClassIndex, Const.CONSTANT_Class); - buf.append(Utility.compactClassName(class_name, false)); + final String className = super.getConstantPool().getConstantString(hostClassIndex, Const.CONSTANT_Class); + buf.append(Utility.compactClassName(className, false)); return buf.toString(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final NestHost c = (NestHost) clone(); - c.setConstantPool(_constant_pool); - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestMembers.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestMembers.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestMembers.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/NestMembers.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,82 +23,95 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and records the classes and interfaces that - * are authorized to claim membership in the nest hosted by the current class or interface. - * There may be at most one NestMembers attribute in a ClassFile structure. + * This class is derived from Attribute and records the classes and interfaces that are authorized to claim + * membership in the nest hosted by the current class or interface. There may be at most one NestMembers attribute in a + * ClassFile structure. * - * @see Attribute + * @see Attribute + * @LastModified: Feb 2023 */ public final class NestMembers extends Attribute { private int[] classes; - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. + * Construct object from input stream. + * + * @param nameIndex Index in constant pool + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - public NestMembers(final NestMembers c) { - this(c.getNameIndex(), c.getLength(), c.getClasses(), c.getConstantPool()); + NestMembers(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (int[]) null, constantPool); + final int classCount = input.readUnsignedShort(); + classes = new int[classCount]; + for (int i = 0; i < classCount; i++) { + classes[i] = input.readUnsignedShort(); + } } - /** - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param classes Table of indices in constant pool - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public NestMembers(final int name_index, final int length, final int[] classes, - final ConstantPool constant_pool) { - super(Const.ATTR_NEST_MEMBERS, name_index, length, constant_pool); - this.classes = classes != null ? classes : new int[0]; + public NestMembers(final int nameIndex, final int length, final int[] classes, final ConstantPool constantPool) { + super(Const.ATTR_NEST_MEMBERS, nameIndex, length, constantPool); + this.classes = classes != null ? classes : Const.EMPTY_INT_ARRAY; + Args.requireU2(this.classes.length, "classes.length"); } - /** - * Construct object from input stream. - * @param name_index Index in constant pool - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. */ - NestMembers(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, (int[]) null, constant_pool); - final int number_of_classes = input.readUnsignedShort(); - classes = new int[number_of_classes]; - for (int i = 0; i < number_of_classes; i++) { - classes[i] = input.readUnsignedShort(); - } + public NestMembers(final NestMembers c) { + this(c.getNameIndex(), c.getLength(), c.getClasses(), c.getConstantPool()); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitNestMembers(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final NestMembers c = (NestMembers) clone(); + if (classes.length > 0) { + c.classes = classes.clone(); + } + c.setConstantPool(constantPool); + return c; + } /** * Dump NestMembers attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(classes.length); for (final int index : classes) { @@ -107,7 +119,6 @@ } } - /** * @return array of indices into constant pool of class names. */ @@ -115,36 +126,28 @@ return classes; } - - /** - * @return Length of classes table. - */ - public int getNumberClasses() { - return classes == null ? 0 : classes.length; - } - - /** * @return string array of class names */ public String[] getClassNames() { final String[] names = new String[classes.length]; - for (int i = 0; i < classes.length; i++) { - names[i] = super.getConstantPool().getConstantString(classes[i], - Const.CONSTANT_Class).replace('/', '.'); - } + Arrays.setAll(names, i -> Utility.pathToPackage(super.getConstantPool().getConstantString(classes[i], Const.CONSTANT_Class))); return names; } - /** - * @param classes the list of class indexes - * Also redefines number_of_classes according to table length. + * @return Length of classes table. */ - public void setClasses( final int[] classes ) { - this.classes = classes != null ? classes : new int[0]; + public int getNumberClasses() { + return classes.length; } + /** + * @param classes the list of class indexes Also redefines number_of_classes according to table length. + */ + public void setClasses(final int[] classes) { + this.classes = classes != null ? classes : Const.EMPTY_INT_ARRAY; + } /** * @return String representation, i.e., a list of classes. @@ -156,25 +159,9 @@ buf.append(classes.length); buf.append("):\n"); for (final int index : classes) { - final String class_name = super.getConstantPool().getConstantString(index, Const.CONSTANT_Class); - buf.append(" ").append(Utility.compactClassName(class_name, false)).append("\n"); + final String className = super.getConstantPool().getConstantString(index, Const.CONSTANT_Class); + buf.append(" ").append(Utility.compactClassName(className, false)).append("\n"); } - return buf.substring(0, buf.length()-1); // remove the last newline - } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final NestMembers c = (NestMembers) clone(); - if (classes != null) { - c.classes = new int[classes.length]; - System.arraycopy(classes, 0, c.classes, 0, - classes.length); - } - c.setConstantPool(_constant_pool); - return c; + return buf.substring(0, buf.length() - 1); // remove the last newline } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,9 +23,8 @@ /** * Denote class to have an accept method(); - * */ public interface Node { - void accept( Visitor obj ); + void accept(Visitor obj); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotationEntry.java 2023-10-06 05:33:33.000000000 +0000 @@ -35,44 +35,48 @@ */ public class ParameterAnnotationEntry implements Node { - private final AnnotationEntry[] annotationTable; + static final ParameterAnnotationEntry[] EMPTY_ARRAY = {}; + public static ParameterAnnotationEntry[] createParameterAnnotationEntries(final Attribute[] attrs) { + // Find attributes that contain parameter annotation data + final List accumulatedAnnotations = new ArrayList<>(attrs.length); + for (final Attribute attribute : attrs) { + if (attribute instanceof ParameterAnnotations) { + final ParameterAnnotations runtimeAnnotations = (ParameterAnnotations) attribute; + Collections.addAll(accumulatedAnnotations, runtimeAnnotations.getParameterAnnotationEntries()); + } + } + return accumulatedAnnotations.toArray(ParameterAnnotationEntry.EMPTY_ARRAY); + } + + private final AnnotationEntry[] annotationTable; /** * Construct object from input stream. * * @param input Input stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - ParameterAnnotationEntry(final DataInput input, final ConstantPool constant_pool) throws IOException { - final int annotation_table_length = input.readUnsignedShort(); - annotationTable = new AnnotationEntry[annotation_table_length]; - for (int i = 0; i < annotation_table_length; i++) { + ParameterAnnotationEntry(final DataInput input, final ConstantPool constantPool) throws IOException { + final int annotationTableLength = input.readUnsignedShort(); + annotationTable = new AnnotationEntry[annotationTableLength]; + for (int i = 0; i < annotationTableLength; i++) { // TODO isRuntimeVisible - annotationTable[i] = AnnotationEntry.read(input, constant_pool, false); + annotationTable[i] = AnnotationEntry.read(input, constantPool, false); } } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitParameterAnnotationEntry(this); } - /** - * returns the array of annotation entries in this annotation - */ - public AnnotationEntry[] getAnnotationEntries() { - return annotationTable; - } - public void dump(final DataOutputStream dos) throws IOException { dos.writeShort(annotationTable.length); for (final AnnotationEntry entry : annotationTable) { @@ -80,15 +84,10 @@ } } - public static ParameterAnnotationEntry[] createParameterAnnotationEntries(final Attribute[] attrs) { - // Find attributes that contain parameter annotation data - final List accumulatedAnnotations = new ArrayList<>(attrs.length); - for (final Attribute attribute : attrs) { - if (attribute instanceof ParameterAnnotations) { - final ParameterAnnotations runtimeAnnotations = (ParameterAnnotations)attribute; - Collections.addAll(accumulatedAnnotations, runtimeAnnotations.getParameterAnnotationEntries()); - } - } - return accumulatedAnnotations.toArray(new ParameterAnnotationEntry[accumulatedAnnotations.size()]); - } + /** + * returns the array of annotation entries in this annotation + */ + public AnnotationEntry[] getAnnotationEntries() { + return annotationTable; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/ParameterAnnotations.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,36 +24,36 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Iterator; +import java.util.stream.Stream; /** * base class for parameter annotations * * @since 6.0 */ -public abstract class ParameterAnnotations extends Attribute { +public abstract class ParameterAnnotations extends Attribute implements Iterable { /** Table of parameter annotations */ private ParameterAnnotationEntry[] parameterAnnotationTable; /** - * @param parameter_annotation_type the subclass type of the parameter annotation - * @param name_index Index pointing to the name Code + * @param parameterAnnotationType the subclass type of the parameter annotation + * @param nameIndex Index pointing to the name Code * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - ParameterAnnotations(final byte parameter_annotation_type, final int name_index, final int length, - final DataInput input, final ConstantPool constant_pool) throws IOException { - this(parameter_annotation_type, name_index, length, (ParameterAnnotationEntry[]) null, - constant_pool); - final int num_parameters = input.readUnsignedByte(); - parameterAnnotationTable = new ParameterAnnotationEntry[num_parameters]; - for (int i = 0; i < num_parameters; i++) { - parameterAnnotationTable[i] = new ParameterAnnotationEntry(input, constant_pool); + ParameterAnnotations(final byte parameterAnnotationType, final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) + throws IOException { + this(parameterAnnotationType, nameIndex, length, (ParameterAnnotationEntry[]) null, constantPool); + final int numParameters = input.readUnsignedByte(); + parameterAnnotationTable = new ParameterAnnotationEntry[numParameters]; + for (int i = 0; i < numParameters; i++) { + parameterAnnotationTable[i] = new ParameterAnnotationEntry(input, constantPool); } } - /** * @param parameterAnnotationType the subclass type of the parameter annotation * @param nameIndex Index pointing to the name Code @@ -62,65 +62,64 @@ * @param constantPool Array of constants */ public ParameterAnnotations(final byte parameterAnnotationType, final int nameIndex, final int length, - final ParameterAnnotationEntry[] parameterAnnotationTable, final ConstantPool constantPool) { + final ParameterAnnotationEntry[] parameterAnnotationTable, final ConstantPool constantPool) { super(parameterAnnotationType, nameIndex, length, constantPool); this.parameterAnnotationTable = parameterAnnotationTable; } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitParameterAnnotation(this); } - /** - * @param parameterAnnotationTable the entries to set in this parameter annotation + * @return deep copy of this attribute */ - public final void setParameterAnnotationTable(final ParameterAnnotationEntry[] parameterAnnotationTable ) { - this.parameterAnnotationTable = parameterAnnotationTable; + @Override + public Attribute copy(final ConstantPool constantPool) { + return (Attribute) clone(); } + @Override + public void dump(final DataOutputStream dos) throws IOException { + super.dump(dos); + dos.writeByte(parameterAnnotationTable.length); + + for (final ParameterAnnotationEntry element : parameterAnnotationTable) { + element.dump(dos); + } + + } /** - * @return the parameter annotation entry table + * returns the array of parameter annotation entries in this parameter annotation */ - public final ParameterAnnotationEntry[] getParameterAnnotationTable() { + public ParameterAnnotationEntry[] getParameterAnnotationEntries() { return parameterAnnotationTable; } - /** - * returns the array of parameter annotation entries in this parameter annotation + * @return the parameter annotation entry table */ - public ParameterAnnotationEntry[] getParameterAnnotationEntries() { + public final ParameterAnnotationEntry[] getParameterAnnotationTable() { return parameterAnnotationTable; } @Override - public void dump(final DataOutputStream dos) throws IOException - { - super.dump(dos); - dos.writeByte(parameterAnnotationTable.length); - - for (final ParameterAnnotationEntry element : parameterAnnotationTable) { - element.dump(dos); - } - + public Iterator iterator() { + return Stream.of(parameterAnnotationTable).iterator(); } /** - * @return deep copy of this attribute + * @param parameterAnnotationTable the entries to set in this parameter annotation */ - @Override - public Attribute copy( final ConstantPool constant_pool ) { - return (Attribute) clone(); + public final void setParameterAnnotationTable(final ParameterAnnotationEntry[] parameterAnnotationTable) { + this.parameterAnnotationTable = parameterAnnotationTable; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,83 +28,83 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class is derived from Attribute and represents a reference - * to a PMG attribute. + * This class is derived from Attribute and represents a reference to a PMG attribute. * - * @see Attribute + * @see Attribute */ public final class PMGClass extends Attribute { private int pmgClassIndex; private int pmgIndex; - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public PMGClass(final PMGClass pgmClass) { - this(pgmClass.getNameIndex(), pgmClass.getLength(), pgmClass.getPMGIndex(), pgmClass.getPMGClassIndex(), - pgmClass.getConstantPool()); - } - - /** * Construct object from input stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 + * + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - PMGClass(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, input.readUnsignedShort(), input.readUnsignedShort(), constant_pool); + PMGClass(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, input.readUnsignedShort(), input.readUnsignedShort(), constantPool); } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param pmgIndex index in constant pool for source file name * @param pmgClassIndex Index in constant pool to CONSTANT_Utf8 * @param constantPool Array of constants */ - public PMGClass(final int name_index, final int length, final int pmgIndex, final int pmgClassIndex, - final ConstantPool constantPool) { - super(Const.ATTR_PMG, name_index, length, constantPool); + public PMGClass(final int nameIndex, final int length, final int pmgIndex, final int pmgClassIndex, final ConstantPool constantPool) { + super(Const.ATTR_PMG, nameIndex, length, constantPool); this.pmgIndex = pmgIndex; this.pmgClassIndex = pmgClassIndex; } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param pgmClass Source to copy. + */ + public PMGClass(final PMGClass pgmClass) { + this(pgmClass.getNameIndex(), pgmClass.getLength(), pgmClass.getPMGIndex(), pgmClass.getPMGClassIndex(), pgmClass.getConstantPool()); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { println("Visiting non-standard PMGClass object"); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + return (Attribute) clone(); + } /** * Dump source file attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(pmgIndex); file.writeShort(pmgClassIndex); } - /** * @return Index in constant pool of source file name. */ @@ -112,15 +112,13 @@ return pmgClassIndex; } - /** - * @param pmgClassIndex + * @return PMG class name. */ - public void setPMGClassIndex( final int pmgClassIndex ) { - this.pmgClassIndex = pmgClassIndex; + public String getPMGClassName() { + return super.getConstantPool().getConstantUtf8(pmgClassIndex).getBytes(); } - /** * @return Index in constant pool of source file name. */ @@ -128,35 +126,27 @@ return pmgIndex; } - /** - * @param pmgIndex + * @return PMG name. */ - public void setPMGIndex( final int pmgIndex ) { - this.pmgIndex = pmgIndex; + public String getPMGName() { + return super.getConstantPool().getConstantUtf8(pmgIndex).getBytes(); } - /** - * @return PMG name. + * @param pmgClassIndex */ - public String getPMGName() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmgIndex, - Const.CONSTANT_Utf8); - return c.getBytes(); + public void setPMGClassIndex(final int pmgClassIndex) { + this.pmgClassIndex = pmgClassIndex; } - /** - * @return PMG class name. + * @param pmgIndex */ - public String getPMGClassName() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(pmgClassIndex, - Const.CONSTANT_Utf8); - return c.getBytes(); + public void setPMGIndex(final int pmgIndex) { + this.pmgIndex = pmgIndex; } - /** * @return String representation */ @@ -164,13 +154,4 @@ public String toString() { return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")"; } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - return (Attribute) clone(); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleAnnotations.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,41 +28,33 @@ import com.sun.org.apache.bcel.internal.Const; /** - * represents an annotation that is represented in the class file but is not - * provided to the JVM. + * represents an annotation that is represented in the class file but is not provided to the JVM. * * @since 6.0 */ -public class RuntimeInvisibleAnnotations extends Annotations -{ +public class RuntimeInvisibleAnnotations extends Annotations { + /** - * @param name_index - * Index pointing to the name Code - * @param length - * Content length in bytes - * @param input - * Input stream - * @param constant_pool - * Array of constants + * @param nameIndex Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException Thrown when an I/O exception of some sort has occurred. */ - public RuntimeInvisibleAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException - { - super(Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS, name_index, length, input, constant_pool, false); + public RuntimeInvisibleAnnotations(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + super(Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS, nameIndex, length, input, constantPool, false); } /** * @return deep copy of this attribute */ @Override - public Attribute copy(final ConstantPool constant_pool) - { + public Attribute copy(final ConstantPool constantPool) { return (Attribute) clone(); } @Override - public final void dump(final DataOutputStream dos) throws IOException - { + public final void dump(final DataOutputStream dos) throws IOException { super.dump(dos); writeAnnotations(dos); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeInvisibleParameterAnnotations.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,21 +27,21 @@ import com.sun.org.apache.bcel.internal.Const; /** - * Represents a parameter annotation that is represented in the class file - * but is not provided to the JVM. + * Represents a parameter annotation that is represented in the class file but is not provided to the JVM. * * @since 6.0 */ public class RuntimeInvisibleParameterAnnotations extends ParameterAnnotations { /** - * @param name_index Index pointing to the name Code + * @param nameIndex Index pointing to the name Code * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants + * @param constantPool Array of constants + * @throws IOException Thrown when an I/O exception of some sort has occurred. */ - public RuntimeInvisibleParameterAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - super(Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, name_index, length, input, constant_pool); + public RuntimeInvisibleParameterAnnotations(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) + throws IOException { + super(Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, nameIndex, length, input, constantPool); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleAnnotations.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,40 +28,33 @@ import com.sun.org.apache.bcel.internal.Const; /** - * represents an annotation that is represented in the class file and is - * provided to the JVM. + * represents an annotation that is represented in the class file and is provided to the JVM. * * @since 6.0 */ -public class RuntimeVisibleAnnotations extends Annotations -{ +public class RuntimeVisibleAnnotations extends Annotations { + /** - * @param name_index - * Index pointing to the name Code - * @param length - * Content length in bytes - * @param input - * Input stream - * @param constant_pool - * Array of constants + * @param nameIndex Index pointing to the name Code + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException Thrown when an I/O exception of some sort has occurred. */ - public RuntimeVisibleAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException - { - super(Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS, name_index, length, input, constant_pool, true); + public RuntimeVisibleAnnotations(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + super(Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS, nameIndex, length, input, constantPool, true); } /** * @return deep copy of this attribute */ @Override - public Attribute copy(final ConstantPool constant_pool) - { + public Attribute copy(final ConstantPool constantPool) { return (Attribute) clone(); } @Override - public final void dump(final DataOutputStream dos) throws IOException - { + public final void dump(final DataOutputStream dos) throws IOException { super.dump(dos); writeAnnotations(dos); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/RuntimeVisibleParameterAnnotations.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,21 +27,21 @@ import com.sun.org.apache.bcel.internal.Const; /** - * Represents a parameter annotation that is represented in the class file - * and is provided to the JVM. + * Represents a parameter annotation that is represented in the class file and is provided to the JVM. * * @since 6.0 */ public class RuntimeVisibleParameterAnnotations extends ParameterAnnotations { /** - * @param name_index Index pointing to the name Code + * @param nameIndex Index pointing to the name Code * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants + * @param constantPool Array of constants + * @throws IOException Thrown when an I/O exception of some sort has occurred. */ - public RuntimeVisibleParameterAnnotations(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - super(Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, name_index, length, input, constant_pool); + public RuntimeVisibleParameterAnnotations(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) + throws IOException { + super(Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, nameIndex, length, input, constantPool); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,122 +25,32 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Objects; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and represents a reference - * to a GJ attribute. + * This class is derived from Attribute and represents a reference to a GJ attribute. * - * @see Attribute + * @see Attribute */ public final class Signature extends Attribute { - private int signatureIndex; - - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Signature(final Signature c) { - this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); - } - - - /** - * Construct object from file stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - Signature(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, input.readUnsignedShort(), constant_pool); - } - - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8 - * @param length Content length in bytes - * @param signatureIndex Index in constant pool to CONSTANT_Utf8 - * @param constant_pool Array of constants - */ - public Signature(final int name_index, final int length, final int signatureIndex, final ConstantPool constant_pool) { - super(Const.ATTR_SIGNATURE, name_index, length, constant_pool); - this.signatureIndex = signatureIndex; - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - //System.err.println("Visiting non-standard Signature object"); - v.visitSignature(this); - } - - - /** - * Dump source file attribute to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public void dump( final DataOutputStream file ) throws IOException { - super.dump(file); - file.writeShort(signatureIndex); - } - - - /** - * @return Index in constant pool of source file name. - */ - public int getSignatureIndex() { - return signatureIndex; - } - - - /** - * @param signatureIndex the index info the constant pool of this signature - */ - public void setSignatureIndex( final int signatureIndex ) { - this.signatureIndex = signatureIndex; - } - - - /** - * @return GJ signature. - */ - public String getSignature() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(signatureIndex, - Const.CONSTANT_Utf8); - return c.getBytes(); - } - /** * Extends ByteArrayInputStream to make 'unreading' chars possible. */ private static final class MyByteArrayInputStream extends ByteArrayInputStream { MyByteArrayInputStream(final String data) { - super(data.getBytes()); + super(data.getBytes(StandardCharsets.UTF_8)); } - String getData() { - return new String(buf); + return new String(buf, StandardCharsets.UTF_8); } - void unread() { if (pos > 0) { pos--; @@ -148,19 +58,59 @@ } } - - private static boolean identStart( final int ch ) { + private static boolean identStart(final int ch) { return ch == 'T' || ch == 'L'; } + // @since 6.0 is no longer final + public static boolean isActualParameterList(final String s) { + return s.startsWith("L") && s.endsWith(">;"); + } + + // @since 6.0 is no longer final + public static boolean isFormalParameterList(final String s) { + return s.startsWith("<") && s.indexOf(':') > 0; + } + + private static void matchGJIdent(final MyByteArrayInputStream in, final StringBuilder buf) { + int ch; + matchIdent(in, buf); + ch = in.read(); + if (ch == '<' || ch == '(') { // Parameterized or method + // System.out.println("Enter <"); + buf.append((char) ch); + matchGJIdent(in, buf); + while ((ch = in.read()) != '>' && ch != ')') { // List of parameters + if (ch == -1) { + throw new IllegalArgumentException("Illegal signature: " + in.getData() + " reaching EOF"); + } + // System.out.println("Still no >"); + buf.append(", "); + in.unread(); + matchGJIdent(in, buf); // Recursive call + } + // System.out.println("Exit >"); + buf.append((char) ch); + } else { + in.unread(); + } + ch = in.read(); + if (identStart(ch)) { + in.unread(); + matchGJIdent(in, buf); + } else if (ch == ')') { + in.unread(); + } else if (ch != ';') { + throw new IllegalArgumentException("Illegal signature: " + in.getData() + " read " + (char) ch); + } + } - private static void matchIdent( final MyByteArrayInputStream in, final StringBuilder buf ) { + private static void matchIdent(final MyByteArrayInputStream in, final StringBuilder buf) { int ch; if ((ch = in.read()) == -1) { - throw new IllegalArgumentException("Illegal signature: " + in.getData() - + " no ident, reaching EOF"); + throw new IllegalArgumentException("Illegal signature: " + in.getData() + " no ident, reaching EOF"); } - //System.out.println("return from ident:" + (char)ch); + // System.out.println("return from ident:" + (char)ch); if (!identStart(ch)) { final StringBuilder buf2 = new StringBuilder(); int count = 1; @@ -170,11 +120,15 @@ ch = in.read(); } if (ch == ':') { // Ok, formal parameter - in.skip("Ljava/lang/Object".length()); + final int skipExpected = "Ljava/lang/Object".length(); + final long skipActual = in.skip(skipExpected); + if (skipActual != skipExpected) { + throw new IllegalStateException(String.format("Unexpected skip: expected=%,d, actual=%,d", skipExpected, skipActual)); + } buf.append(buf2); ch = in.read(); in.unread(); - //System.out.println("so far:" + buf2 + ":next:" +(char)ch); + // System.out.println("so far:" + buf2 + ":next:" +(char)ch); } else { for (int i = 0; i < count; i++) { in.unread(); @@ -187,87 +141,118 @@ do { buf2.append((char) ch); ch = in.read(); - //System.out.println("within ident:"+ (char)ch); - } while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/'))); - buf.append(buf2.toString().replace('/', '.')); - //System.out.println("regular return ident:"+ (char)ch + ":" + buf2); + // System.out.println("within ident:"+ (char)ch); + } while (ch != -1 && (Character.isJavaIdentifierPart((char) ch) || ch == '/')); + buf.append(Utility.pathToPackage(buf2.toString())); + // System.out.println("regular return ident:"+ (char)ch + ":" + buf2); if (ch != -1) { in.unread(); } } - - private static void matchGJIdent( final MyByteArrayInputStream in, final StringBuilder buf ) { - int ch; - matchIdent(in, buf); - ch = in.read(); - if ((ch == '<') || ch == '(') { // Parameterized or method - //System.out.println("Enter <"); - buf.append((char) ch); - matchGJIdent(in, buf); - while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters - if (ch == -1) { - throw new IllegalArgumentException("Illegal signature: " + in.getData() - + " reaching EOF"); - } - //System.out.println("Still no >"); - buf.append(", "); - in.unread(); - matchGJIdent(in, buf); // Recursive call - } - //System.out.println("Exit >"); - buf.append((char) ch); - } else { - in.unread(); - } - ch = in.read(); - if (identStart(ch)) { - in.unread(); - matchGJIdent(in, buf); - } else if (ch == ')') { - in.unread(); - return; - } else if (ch != ';') { - throw new IllegalArgumentException("Illegal signature: " + in.getData() + " read " + (char) ch); - } - } - - - public static String translate( final String s ) { - //System.out.println("Sig:" + s); + public static String translate(final String s) { + // System.out.println("Sig:" + s); final StringBuilder buf = new StringBuilder(); matchGJIdent(new MyByteArrayInputStream(s), buf); return buf.toString(); } + private int signatureIndex; - // @since 6.0 is no longer final - public static boolean isFormalParameterList( final String s ) { - return s.startsWith("<") && (s.indexOf(':') > 0); + /** + * Construct object from file stream. + * + * @param nameIndex Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. + */ + Signature(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, input.readUnsignedShort(), constantPool); } - - // @since 6.0 is no longer final - public static boolean isActualParameterList( final String s ) { - return s.startsWith("L") && s.endsWith(">;"); + /** + * @param nameIndex Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param signatureIndex Index in constant pool to CONSTANT_Utf8 + * @param constantPool Array of constants + */ + public Signature(final int nameIndex, final int length, final int signatureIndex, final ConstantPool constantPool) { + super(Const.ATTR_SIGNATURE, nameIndex, Args.require(length, 2, "Signature length attribute"), constantPool); + this.signatureIndex = signatureIndex; + // validate: + Objects.requireNonNull(constantPool.getConstantUtf8(signatureIndex), "constantPool.getConstantUtf8(signatureIndex)"); } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. + */ + public Signature(final Signature c) { + this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); + } /** - * @return String representation + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object */ @Override - public String toString() { - final String s = getSignature(); - return "Signature: " + s; + public void accept(final Visitor v) { + // System.err.println("Visiting non-standard Signature object"); + v.visitSignature(this); } - /** * @return deep copy of this attribute */ @Override - public Attribute copy( final ConstantPool _constant_pool ) { + public Attribute copy(final ConstantPool constantPool) { return (Attribute) clone(); } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException if an I/O error occurs. + */ + @Override + public void dump(final DataOutputStream file) throws IOException { + super.dump(file); + file.writeShort(signatureIndex); + } + + /** + * @return GJ signature. + */ + public String getSignature() { + return super.getConstantPool().getConstantUtf8(signatureIndex).getBytes(); + } + + /** + * @return Index in constant pool of source file name. + */ + public int getSignatureIndex() { + return signatureIndex; + } + + /** + * @param signatureIndex the index info the constant pool of this signature + */ + public void setSignatureIndex(final int signatureIndex) { + this.signatureIndex = signatureIndex; + } + + /** + * @return String representation + */ + @Override + public String toString() { + return "Signature: " + getSignature(); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SimpleElementValue.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,201 +29,155 @@ /** * @since 6.0 */ -public class SimpleElementValue extends ElementValue -{ +public class SimpleElementValue extends ElementValue { private int index; - public SimpleElementValue(final int type, final int index, final ConstantPool cpool) - { + public SimpleElementValue(final int type, final int index, final ConstantPool cpool) { super(type, cpool); this.index = index; } + @Override + public void dump(final DataOutputStream dos) throws IOException { + final int type = super.getType(); + dos.writeByte(type); // u1 kind of value + switch (type) { + case PRIMITIVE_INT: + case PRIMITIVE_BYTE: + case PRIMITIVE_CHAR: + case PRIMITIVE_FLOAT: + case PRIMITIVE_LONG: + case PRIMITIVE_BOOLEAN: + case PRIMITIVE_SHORT: + case PRIMITIVE_DOUBLE: + case STRING: + dos.writeShort(getIndex()); + break; + default: + throw new ClassFormatException("SimpleElementValue doesnt know how to write out type " + type); + } + } + /** * @return Value entry index in the cpool */ - public int getIndex() - { + public int getIndex() { return index; } - public void setIndex(final int index) - { - this.index = index; - } - - public String getValueString() - { - if (super.getType() != STRING) { - throw new IllegalStateException( - "Dont call getValueString() on a non STRING ElementValue"); - } - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(getIndex(), - Const.CONSTANT_Utf8); - return c.getBytes(); - } - - public int getValueInt() - { - if (super.getType() != PRIMITIVE_INT) { - throw new IllegalStateException( - "Dont call getValueString() on a non STRING ElementValue"); + public boolean getValueBoolean() { + if (super.getType() != PRIMITIVE_BOOLEAN) { + throw new IllegalStateException("Dont call getValueBoolean() on a non BOOLEAN ElementValue"); } - final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), - Const.CONSTANT_Integer); - return c.getBytes(); + final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); + return bo.getBytes() != 0; } - public byte getValueByte() - { + public byte getValueByte() { if (super.getType() != PRIMITIVE_BYTE) { - throw new IllegalStateException( - "Dont call getValueByte() on a non BYTE ElementValue"); + throw new IllegalStateException("Dont call getValueByte() on a non BYTE ElementValue"); } - final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), - Const.CONSTANT_Integer); - return (byte) c.getBytes(); + return (byte) super.getConstantPool().getConstantInteger(getIndex()).getBytes(); } - public char getValueChar() - { + public char getValueChar() { if (super.getType() != PRIMITIVE_CHAR) { - throw new IllegalStateException( - "Dont call getValueChar() on a non CHAR ElementValue"); + throw new IllegalStateException("Dont call getValueChar() on a non CHAR ElementValue"); } - final ConstantInteger c = (ConstantInteger) super.getConstantPool().getConstant(getIndex(), - Const.CONSTANT_Integer); - return (char) c.getBytes(); + return (char) super.getConstantPool().getConstantInteger(getIndex()).getBytes(); } - public long getValueLong() - { - if (super.getType() != PRIMITIVE_LONG) { - throw new IllegalStateException( - "Dont call getValueLong() on a non LONG ElementValue"); + public double getValueDouble() { + if (super.getType() != PRIMITIVE_DOUBLE) { + throw new IllegalStateException("Dont call getValueDouble() on a non DOUBLE ElementValue"); } - final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex()); - return j.getBytes(); + final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex()); + return d.getBytes(); } - public float getValueFloat() - { + public float getValueFloat() { if (super.getType() != PRIMITIVE_FLOAT) { - throw new IllegalStateException( - "Dont call getValueFloat() on a non FLOAT ElementValue"); + throw new IllegalStateException("Dont call getValueFloat() on a non FLOAT ElementValue"); } final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex()); return f.getBytes(); } - public double getValueDouble() - { - if (super.getType() != PRIMITIVE_DOUBLE) { - throw new IllegalStateException( - "Dont call getValueDouble() on a non DOUBLE ElementValue"); + public int getValueInt() { + if (super.getType() != PRIMITIVE_INT) { + throw new IllegalStateException("Dont call getValueInt() on a non INT ElementValue"); } - final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex()); - return d.getBytes(); + return super.getConstantPool().getConstantInteger(getIndex()).getBytes(); } - public boolean getValueBoolean() - { - if (super.getType() != PRIMITIVE_BOOLEAN) { - throw new IllegalStateException( - "Dont call getValueBoolean() on a non BOOLEAN ElementValue"); + public long getValueLong() { + if (super.getType() != PRIMITIVE_LONG) { + throw new IllegalStateException("Dont call getValueLong() on a non LONG ElementValue"); } - final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); - return bo.getBytes() != 0; + final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex()); + return j.getBytes(); } - public short getValueShort() - { + public short getValueShort() { if (super.getType() != PRIMITIVE_SHORT) { - throw new IllegalStateException( - "Dont call getValueShort() on a non SHORT ElementValue"); + throw new IllegalStateException("Dont call getValueShort() on a non SHORT ElementValue"); } final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex()); return (short) s.getBytes(); } - @Override - public String toString() - { - return stringifyValue(); + public String getValueString() { + if (super.getType() != STRING) { + throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue"); + } + return super.getConstantPool().getConstantUtf8(getIndex()).getBytes(); + } + + public void setIndex(final int index) { + this.index = index; } // Whatever kind of value it is, return it as a string @Override - public String stringifyValue() - { + public String stringifyValue() { final ConstantPool cpool = super.getConstantPool(); - final int _type = super.getType(); - switch (_type) - { + final int type = super.getType(); + switch (type) { case PRIMITIVE_INT: - final ConstantInteger c = (ConstantInteger) cpool.getConstant(getIndex(), - Const.CONSTANT_Integer); - return Integer.toString(c.getBytes()); + return Integer.toString(cpool.getConstantInteger(getIndex()).getBytes()); case PRIMITIVE_LONG: - final ConstantLong j = (ConstantLong) cpool.getConstant(getIndex(), - Const.CONSTANT_Long); + final ConstantLong j = cpool.getConstant(getIndex(), Const.CONSTANT_Long, ConstantLong.class); return Long.toString(j.getBytes()); case PRIMITIVE_DOUBLE: - final ConstantDouble d = (ConstantDouble) cpool.getConstant(getIndex(), - Const.CONSTANT_Double); + final ConstantDouble d = cpool.getConstant(getIndex(), Const.CONSTANT_Double, ConstantDouble.class); return Double.toString(d.getBytes()); case PRIMITIVE_FLOAT: - final ConstantFloat f = (ConstantFloat) cpool.getConstant(getIndex(), - Const.CONSTANT_Float); + final ConstantFloat f = cpool.getConstant(getIndex(), Const.CONSTANT_Float, ConstantFloat.class); return Float.toString(f.getBytes()); case PRIMITIVE_SHORT: - final ConstantInteger s = (ConstantInteger) cpool.getConstant(getIndex(), - Const.CONSTANT_Integer); + final ConstantInteger s = cpool.getConstantInteger(getIndex()); return Integer.toString(s.getBytes()); case PRIMITIVE_BYTE: - final ConstantInteger b = (ConstantInteger) cpool.getConstant(getIndex(), - Const.CONSTANT_Integer); + final ConstantInteger b = cpool.getConstantInteger(getIndex()); return Integer.toString(b.getBytes()); case PRIMITIVE_CHAR: - final ConstantInteger ch = (ConstantInteger) cpool.getConstant( - getIndex(), Const.CONSTANT_Integer); - return String.valueOf((char)ch.getBytes()); + final ConstantInteger ch = cpool.getConstantInteger(getIndex()); + return String.valueOf((char) ch.getBytes()); case PRIMITIVE_BOOLEAN: - final ConstantInteger bo = (ConstantInteger) cpool.getConstant( - getIndex(), Const.CONSTANT_Integer); + final ConstantInteger bo = cpool.getConstantInteger(getIndex()); if (bo.getBytes() == 0) { return "false"; } return "true"; case STRING: - final ConstantUtf8 cu8 = (ConstantUtf8) cpool.getConstant(getIndex(), - Const.CONSTANT_Utf8); - return cu8.getBytes(); + return cpool.getConstantUtf8(getIndex()).getBytes(); default: - throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + _type); + throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + type); } } @Override - public void dump(final DataOutputStream dos) throws IOException - { - final int _type = super.getType(); - dos.writeByte(_type); // u1 kind of value - switch (_type) - { - case PRIMITIVE_INT: - case PRIMITIVE_BYTE: - case PRIMITIVE_CHAR: - case PRIMITIVE_FLOAT: - case PRIMITIVE_LONG: - case PRIMITIVE_BOOLEAN: - case PRIMITIVE_SHORT: - case PRIMITIVE_DOUBLE: - case STRING: - dos.writeShort(getIndex()); - break; - default: - throw new IllegalStateException("SimpleElementValue doesnt know how to write out type " + _type); - } + public String toString() { + return stringifyValue(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,88 +26,87 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and represents a reference - * to the source file of this class. At most one SourceFile attribute - * should appear per classfile. The intention of this class is that it is - * instantiated from the Attribute.readAttribute() method. + * This class is derived from Attribute and represents a reference to the source file of this class. At most + * one SourceFile attribute should appear per classfile. The intention of this class is that it is instantiated from the + * Attribute.readAttribute() method. * - * @see Attribute + * @see Attribute */ public final class SourceFile extends Attribute { private int sourceFileIndex; - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public SourceFile(final SourceFile c) { - this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); - } - - /** * Construct object from input stream. - * @param name_index Index in constant pool to CONSTANT_Utf8 + * + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - SourceFile(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, input.readUnsignedShort(), constant_pool); + SourceFile(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, input.readUnsignedShort(), constantPool); } - /** - * @param name_index Index in constant pool to CONSTANT_Utf8, which - * should represent the string "SourceFile". + * @param nameIndex Index in constant pool to CONSTANT_Utf8, which should represent the string "SourceFile". * @param length Content length in bytes, the value should be 2. - * @param constantPool The constant pool that this attribute is - * associated with. - * @param sourceFileIndex Index in constant pool to CONSTANT_Utf8. This - * string will be interpreted as the name of the file from which this - * class was compiled. It will not be interpreted as indicating the name - * of the directory contqining the file or an absolute path; this - * information has to be supplied the consumer of this attribute - in - * many cases, the JVM. + * @param constantPool The constant pool that this attribute is associated with. + * @param sourceFileIndex Index in constant pool to CONSTANT_Utf8. This string will be interpreted as the name of the + * file from which this class was compiled. It will not be interpreted as indicating the name of the directory + * contqining the file or an absolute path; this information has to be supplied the consumer of this attribute - + * in many cases, the JVM. */ - public SourceFile(final int name_index, final int length, final int sourceFileIndex, final ConstantPool constantPool) { - super(Const.ATTR_SOURCE_FILE, name_index, length, constantPool); - this.sourceFileIndex = sourceFileIndex; + public SourceFile(final int nameIndex, final int length, final int sourceFileIndex, final ConstantPool constantPool) { + super(Const.ATTR_SOURCE_FILE, nameIndex, Args.require(length, 2, "SourceFile length attribute"), constantPool); + this.sourceFileIndex = Args.requireU2(sourceFileIndex, 0, constantPool.getLength(), "SourceFile source file index"); } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a + * physical copy. + * + * @param c Source to copy. + */ + public SourceFile(final SourceFile c) { + this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitSourceFile(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + return (Attribute) clone(); + } /** * Dump source file attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); file.writeShort(sourceFileIndex); } - /** * @return Index in constant pool of source file name. */ @@ -115,25 +114,20 @@ return sourceFileIndex; } - /** - * @param sourceFileIndex + * @return Source file name. */ - public void setSourceFileIndex( final int sourceFileIndex ) { - this.sourceFileIndex = sourceFileIndex; + public String getSourceFileName() { + return super.getConstantPool().getConstantUtf8(sourceFileIndex).getBytes(); } - /** - * @return Source file name. + * @param sourceFileIndex */ - public String getSourceFileName() { - final ConstantUtf8 c = (ConstantUtf8) super.getConstantPool().getConstant(sourceFileIndex, - Const.CONSTANT_Utf8); - return c.getBytes(); + public void setSourceFileIndex(final int sourceFileIndex) { + this.sourceFileIndex = sourceFileIndex; } - /** * @return String representation */ @@ -141,13 +135,4 @@ public String toString() { return "SourceFile: " + getSourceFileName(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - return (Attribute) clone(); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,18 +24,33 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; + import com.sun.org.apache.bcel.internal.Const; /** - * This class represents a stack map entry recording the types of - * local variables and the the of stack items at a given byte code offset. - * See CLDC specification 5.3.1.2 + * This class represents a stack map entry recording the types of local variables and the of stack items at a given + * byte code offset. See CLDC specification 5.3.1.2. + * + * See also https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.4 * - * @see StackMap - * @see StackMapType + *
    + * union stack_map_frame {
    + *   same_frame;
    + *   same_locals_1_stack_item_frame;
    + *   same_locals_1_stack_item_frame_extended;
    + *   chop_frame;
    + *   same_frame_extended;
    + *   append_frame;
    + *   full_frame;
    + * }
    + * 
    + * @see StackMap + * @see StackMapType */ -public final class StackMapEntry implements Node, Cloneable -{ +public final class StackMapEntry implements Node, Cloneable { + + static final StackMapEntry[] EMPTY_ARRAY = {}; private int frameType; private int byteCodeOffset; @@ -43,53 +58,49 @@ private StackMapType[] typesOfStackItems; private ConstantPool constantPool; - /** * Construct object from input stream. * - * @param input Input stream - * @throws IOException + * @param dataInput Input stream + * @throws IOException if an I/O error occurs. */ - StackMapEntry(final DataInput input, final ConstantPool constantPool) throws IOException { - this(input.readByte() & 0xFF, -1, null, null, constantPool); + StackMapEntry(final DataInput dataInput, final ConstantPool constantPool) throws IOException { + this(dataInput.readByte() & 0xFF, -1, null, null, constantPool); if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { byteCodeOffset = frameType - Const.SAME_FRAME; - } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { byteCodeOffset = frameType - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; - typesOfStackItems = new StackMapType[1]; - typesOfStackItems[0] = new StackMapType(input, constantPool); + typesOfStackItems = new StackMapType[] { new StackMapType(dataInput, constantPool) }; } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - byteCodeOffset = input.readShort(); - typesOfStackItems = new StackMapType[1]; - typesOfStackItems[0] = new StackMapType(input, constantPool); + byteCodeOffset = dataInput.readUnsignedShort(); + typesOfStackItems = new StackMapType[] { new StackMapType(dataInput, constantPool) }; } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { - byteCodeOffset = input.readShort(); + byteCodeOffset = dataInput.readUnsignedShort(); } else if (frameType == Const.SAME_FRAME_EXTENDED) { - byteCodeOffset = input.readShort(); + byteCodeOffset = dataInput.readUnsignedShort(); } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { - byteCodeOffset = input.readShort(); - final int number_of_locals = frameType - 251; - typesOfLocals = new StackMapType[number_of_locals]; - for (int i = 0; i < number_of_locals; i++) { - typesOfLocals[i] = new StackMapType(input, constantPool); + byteCodeOffset = dataInput.readUnsignedShort(); + final int numberOfLocals = frameType - 251; + typesOfLocals = new StackMapType[numberOfLocals]; + for (int i = 0; i < numberOfLocals; i++) { + typesOfLocals[i] = new StackMapType(dataInput, constantPool); } } else if (frameType == Const.FULL_FRAME) { - byteCodeOffset = input.readShort(); - final int number_of_locals = input.readShort(); - typesOfLocals = new StackMapType[number_of_locals]; - for (int i = 0; i < number_of_locals; i++) { - typesOfLocals[i] = new StackMapType(input, constantPool); - } - final int number_of_stack_items = input.readShort(); - typesOfStackItems = new StackMapType[number_of_stack_items]; - for (int i = 0; i < number_of_stack_items; i++) { - typesOfStackItems[i] = new StackMapType(input, constantPool); + byteCodeOffset = dataInput.readUnsignedShort(); + final int numberOfLocals = dataInput.readUnsignedShort(); + typesOfLocals = new StackMapType[numberOfLocals]; + for (int i = 0; i < numberOfLocals; i++) { + typesOfLocals[i] = new StackMapType(dataInput, constantPool); + } + final int numberOfStackItems = dataInput.readUnsignedShort(); + typesOfStackItems = new StackMapType[numberOfStackItems]; + for (int i = 0; i < numberOfStackItems; i++) { + typesOfStackItems[i] = new StackMapType(dataInput, constantPool); } } else { /* Can't happen */ - throw new ClassFormatException ("Invalid frame type found while parsing stack map table: " + frameType); + throw new ClassFormatException("Invalid frame type found while parsing stack map table: " + frameType); } } @@ -102,17 +113,21 @@ * @param numberOfStackItems NOT USED * @param typesOfStackItems array ot {@link StackMapType}s of stack items * @param constantPool the constant pool - * @deprecated Since 6.0, use {@link #StackMapEntry(int, int, StackMapType[], StackMapType[], ConstantPool)} - * instead + * @deprecated Since 6.0, use {@link #StackMapEntry(int, int, StackMapType[], StackMapType[], ConstantPool)} instead */ @java.lang.Deprecated - public StackMapEntry(final int byteCodeOffset, final int numberOfLocals, - final StackMapType[] typesOfLocals, final int numberOfStackItems, - final StackMapType[] typesOfStackItems, final ConstantPool constantPool) { + public StackMapEntry(final int byteCodeOffset, final int numberOfLocals, final StackMapType[] typesOfLocals, final int numberOfStackItems, + final StackMapType[] typesOfStackItems, final ConstantPool constantPool) { this.byteCodeOffset = byteCodeOffset; - this.typesOfLocals = typesOfLocals != null ? typesOfLocals : new StackMapType[0]; - this.typesOfStackItems = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0]; + this.typesOfLocals = typesOfLocals != null ? typesOfLocals : StackMapType.EMPTY_ARRAY; + this.typesOfStackItems = typesOfStackItems != null ? typesOfStackItems : StackMapType.EMPTY_ARRAY; this.constantPool = constantPool; + if (numberOfLocals < 0) { + throw new IllegalArgumentException("numberOfLocals < 0"); + } + if (numberOfStackItems < 0) { + throw new IllegalArgumentException("numberOfStackItems < 0"); + } } /** @@ -124,29 +139,53 @@ * @param typesOfStackItems array ot {@link StackMapType}s of stack items * @param constantPool the constant pool */ - public StackMapEntry(final int tag, final int byteCodeOffset, - final StackMapType[] typesOfLocals, - final StackMapType[] typesOfStackItems, final ConstantPool constantPool) { + public StackMapEntry(final int tag, final int byteCodeOffset, final StackMapType[] typesOfLocals, final StackMapType[] typesOfStackItems, + final ConstantPool constantPool) { this.frameType = tag; this.byteCodeOffset = byteCodeOffset; - this.typesOfLocals = typesOfLocals != null ? typesOfLocals : new StackMapType[0]; - this.typesOfStackItems = typesOfStackItems != null ? typesOfStackItems : new StackMapType[0]; + this.typesOfLocals = typesOfLocals != null ? typesOfLocals : StackMapType.EMPTY_ARRAY; + this.typesOfStackItems = typesOfStackItems != null ? typesOfStackItems : StackMapType.EMPTY_ARRAY; this.constantPool = constantPool; } + /** + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackMapEntry(this); + } + + /** + * @return deep copy of this object + */ + public StackMapEntry copy() { + StackMapEntry e; + try { + e = (StackMapEntry) clone(); + } catch (final CloneNotSupportedException ex) { + throw new Error("Clone Not Supported"); + } + + e.typesOfLocals = new StackMapType[typesOfLocals.length]; + Arrays.setAll(e.typesOfLocals, i -> typesOfLocals[i].copy()); + e.typesOfStackItems = new StackMapType[typesOfStackItems.length]; + Arrays.setAll(e.typesOfStackItems, i -> typesOfStackItems[i].copy()); + return e; + } /** * Dump stack map entry * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.write(frameType); - if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { - // nothing to be done - } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { typesOfStackItems[0].dump(file); } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { file.writeShort(byteCodeOffset); @@ -170,63 +209,26 @@ for (final StackMapType type : typesOfStackItems) { type.dump(file); } - } else { + } else if (!(frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX)) { /* Can't happen */ - throw new ClassFormatException ("Invalid Stack map table tag: " + frameType); + throw new ClassFormatException("Invalid Stack map table tag: " + frameType); } } + public int getByteCodeOffset() { + return byteCodeOffset; + } /** - * @return String representation. + * @return Constant pool used by this object. */ - @Override - public String toString() { - final StringBuilder buf = new StringBuilder(64); - buf.append("("); - if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { - buf.append("SAME"); - } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - buf.append("SAME_LOCALS_1_STACK"); - } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - buf.append("SAME_LOCALS_1_STACK_EXTENDED"); - } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { - buf.append("CHOP ").append(String.valueOf(251-frameType)); - } else if (frameType == Const.SAME_FRAME_EXTENDED) { - buf.append("SAME_EXTENDED"); - } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { - buf.append("APPEND ").append(String.valueOf(frameType-251)); - } else if (frameType == Const.FULL_FRAME) { - buf.append("FULL"); - } else { - buf.append("UNKNOWN (").append(frameType).append(")"); - } - buf.append(", offset delta=").append(byteCodeOffset); - if (typesOfLocals.length > 0) { - buf.append(", locals={"); - for (int i = 0; i < typesOfLocals.length; i++) { - buf.append(typesOfLocals[i]); - if (i < typesOfLocals.length - 1) { - buf.append(", "); - } - } - buf.append("}"); - } - if (typesOfStackItems.length > 0) { - buf.append(", stack items={"); - for (int i = 0; i < typesOfStackItems.length; i++) { - buf.append(typesOfStackItems[i]); - if (i < typesOfStackItems.length - 1) { - buf.append(", "); - } - } - buf.append("}"); - } - buf.append(")"); - return buf.toString(); + public ConstantPool getConstantPool() { + return constantPool; } + public int getFrameType() { + return frameType; + } /** * Calculate stack map entry size @@ -235,205 +237,183 @@ int getMapEntrySize() { if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { return 1; - } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + } + if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { return 1 + (typesOfStackItems[0].hasIndex() ? 3 : 1); - } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + } + if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { return 3 + (typesOfStackItems[0].hasIndex() ? 3 : 1); - } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { - return 3; - } else if (frameType == Const.SAME_FRAME_EXTENDED) { + } + if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX || frameType == Const.SAME_FRAME_EXTENDED) { return 3; - } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { + } + if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { int len = 3; - for (final StackMapType types_of_local : typesOfLocals) { - len += types_of_local.hasIndex() ? 3 : 1; - } - return len; - } else if (frameType == Const.FULL_FRAME) { - int len = 7; - for (final StackMapType types_of_local : typesOfLocals) { - len += types_of_local.hasIndex() ? 3 : 1; - } - for (final StackMapType types_of_stack_item : typesOfStackItems) { - len += types_of_stack_item.hasIndex() ? 3 : 1; + for (final StackMapType typesOfLocal : typesOfLocals) { + len += typesOfLocal.hasIndex() ? 3 : 1; } return len; - } else { + } + if (frameType != Const.FULL_FRAME) { throw new IllegalStateException("Invalid StackMap frameType: " + frameType); } + int len = 7; + for (final StackMapType typesOfLocal : typesOfLocals) { + len += typesOfLocal.hasIndex() ? 3 : 1; + } + for (final StackMapType typesOfStackItem : typesOfStackItems) { + len += typesOfStackItem.hasIndex() ? 3 : 1; + } + return len; } + public int getNumberOfLocals() { + return typesOfLocals.length; + } - public void setFrameType( final int f ) { - if (f >= Const.SAME_FRAME && f <= Const.SAME_FRAME_MAX) { - byteCodeOffset = f - Const.SAME_FRAME; - } else if (f >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - f <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - byteCodeOffset = f - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; - } else if (f == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock - } else if (f >= Const.CHOP_FRAME && f <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock - } else if (f == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock - } else if (f >= Const.APPEND_FRAME && f <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock - } else if (f == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock - } else { - throw new IllegalArgumentException("Invalid StackMap frameType"); - } - frameType = f; + public int getNumberOfStackItems() { + return typesOfStackItems.length; } + public StackMapType[] getTypesOfLocals() { + return typesOfLocals; + } - public int getFrameType() { - return frameType; + public StackMapType[] getTypesOfStackItems() { + return typesOfStackItems; } + private boolean invalidFrameType(final int f) { + // @formatter:off + return f != Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED + && !(f >= Const.CHOP_FRAME && f <= Const.CHOP_FRAME_MAX) + && f != Const.SAME_FRAME_EXTENDED + && !(f >= Const.APPEND_FRAME && f <= Const.APPEND_FRAME_MAX) + && f != Const.FULL_FRAME; + // @formatter:on + } - public void setByteCodeOffset( final int new_offset ) { - if (new_offset < 0 || new_offset > 32767) { - throw new IllegalArgumentException("Invalid StackMap offset: " + new_offset); + public void setByteCodeOffset(final int newOffset) { + if (newOffset < 0 || newOffset > 32767) { + throw new IllegalArgumentException("Invalid StackMap offset: " + newOffset); } - if (frameType >= Const.SAME_FRAME && - frameType <= Const.SAME_FRAME_MAX) { - if (new_offset > Const.SAME_FRAME_MAX) { + if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { + if (newOffset > Const.SAME_FRAME_MAX) { frameType = Const.SAME_FRAME_EXTENDED; } else { - frameType = new_offset; + frameType = newOffset; } - } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && - frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { - if (new_offset > Const.SAME_FRAME_MAX) { + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + if (newOffset > Const.SAME_FRAME_MAX) { frameType = Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; } else { - frameType = Const.SAME_LOCALS_1_STACK_ITEM_FRAME + new_offset; + frameType = Const.SAME_LOCALS_1_STACK_ITEM_FRAME + newOffset; } - } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frameType >= Const.CHOP_FRAME && - frameType <= Const.CHOP_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frameType == Const.SAME_FRAME_EXTENDED) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frameType >= Const.APPEND_FRAME && - frameType <= Const.APPEND_FRAME_MAX) { // CHECKSTYLE IGNORE EmptyBlock - } else if (frameType == Const.FULL_FRAME) { // CHECKSTYLE IGNORE EmptyBlock - } else { + } else if (invalidFrameType(frameType)) { throw new IllegalStateException("Invalid StackMap frameType: " + frameType); } - byteCodeOffset = new_offset; + byteCodeOffset = newOffset; } - /** - * Update the distance (as an offset delta) from this StackMap - * entry to the next. Note that this might cause the the - * frame type to change. Note also that delta may be negative. - * - * @param delta offset delta + * @param constantPool Constant pool to be used for this object. */ - public void updateByteCodeOffset(final int delta) { - setByteCodeOffset(byteCodeOffset + delta); + public void setConstantPool(final ConstantPool constantPool) { + this.constantPool = constantPool; } - - public int getByteCodeOffset() { - return byteCodeOffset; + public void setFrameType(final int ft) { + if (ft >= Const.SAME_FRAME && ft <= Const.SAME_FRAME_MAX) { + byteCodeOffset = ft - Const.SAME_FRAME; + } else if (ft >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && ft <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + byteCodeOffset = ft - Const.SAME_LOCALS_1_STACK_ITEM_FRAME; + } else if (invalidFrameType(ft)) { + throw new IllegalArgumentException("Invalid StackMap frameType"); + } + frameType = ft; } - /** * * @deprecated since 6.0 */ @java.lang.Deprecated - public void setNumberOfLocals( final int n ) { // TODO unused - } - - - public int getNumberOfLocals() { - return typesOfLocals.length; + public void setNumberOfLocals(final int n) { // TODO unused } - - public void setTypesOfLocals( final StackMapType[] types ) { - typesOfLocals = types != null ? types : new StackMapType[0]; - } - - - public StackMapType[] getTypesOfLocals() { - return typesOfLocals; - } - - /** * * @deprecated since 6.0 */ @java.lang.Deprecated - public void setNumberOfStackItems( final int n ) { // TODO unused - } - - - public int getNumberOfStackItems() { - return typesOfStackItems.length; + public void setNumberOfStackItems(final int n) { // TODO unused } - - public void setTypesOfStackItems( final StackMapType[] types ) { - typesOfStackItems = types != null ? types : new StackMapType[0]; + public void setTypesOfLocals(final StackMapType[] types) { + typesOfLocals = types != null ? types : StackMapType.EMPTY_ARRAY; } - - public StackMapType[] getTypesOfStackItems() { - return typesOfStackItems; + public void setTypesOfStackItems(final StackMapType[] types) { + typesOfStackItems = types != null ? types : StackMapType.EMPTY_ARRAY; } - /** - * @return deep copy of this object + * @return String representation. */ - public StackMapEntry copy() { - StackMapEntry e; - try { - e = (StackMapEntry) clone(); - } catch (final CloneNotSupportedException ex) { - throw new Error("Clone Not Supported"); + @Override + public String toString() { + final StringBuilder buf = new StringBuilder(64); + buf.append("("); + if (frameType >= Const.SAME_FRAME && frameType <= Const.SAME_FRAME_MAX) { + buf.append("SAME"); + } else if (frameType >= Const.SAME_LOCALS_1_STACK_ITEM_FRAME && frameType <= Const.SAME_LOCALS_1_STACK_ITEM_FRAME_MAX) { + buf.append("SAME_LOCALS_1_STACK"); + } else if (frameType == Const.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { + buf.append("SAME_LOCALS_1_STACK_EXTENDED"); + } else if (frameType >= Const.CHOP_FRAME && frameType <= Const.CHOP_FRAME_MAX) { + buf.append("CHOP ").append(String.valueOf(251 - frameType)); + } else if (frameType == Const.SAME_FRAME_EXTENDED) { + buf.append("SAME_EXTENDED"); + } else if (frameType >= Const.APPEND_FRAME && frameType <= Const.APPEND_FRAME_MAX) { + buf.append("APPEND ").append(String.valueOf(frameType - 251)); + } else if (frameType == Const.FULL_FRAME) { + buf.append("FULL"); + } else { + buf.append("UNKNOWN (").append(frameType).append(")"); } - - e.typesOfLocals = new StackMapType[typesOfLocals.length]; - for (int i = 0; i < typesOfLocals.length; i++) { - e.typesOfLocals[i] = typesOfLocals[i].copy(); + buf.append(", offset delta=").append(byteCodeOffset); + if (typesOfLocals.length > 0) { + buf.append(", locals={"); + for (int i = 0; i < typesOfLocals.length; i++) { + buf.append(typesOfLocals[i]); + if (i < typesOfLocals.length - 1) { + buf.append(", "); + } + } + buf.append("}"); } - e.typesOfStackItems = new StackMapType[typesOfStackItems.length]; - for (int i = 0; i < typesOfStackItems.length; i++) { - e.typesOfStackItems[i] = typesOfStackItems[i].copy(); + if (typesOfStackItems.length > 0) { + buf.append(", stack items={"); + for (int i = 0; i < typesOfStackItems.length; i++) { + buf.append(typesOfStackItems[i]); + if (i < typesOfStackItems.length - 1) { + buf.append(", "); + } + } + buf.append("}"); } - return e; + buf.append(")"); + return buf.toString(); } - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Update the distance (as an offset delta) from this StackMap entry to the next. Note that this might cause the + * frame type to change. Note also that delta may be negative. * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitStackMapEntry(this); - } - - - /** - * @return Constant pool used by this object. - */ - public ConstantPool getConstantPool() { - return constantPool; - } - - - /** - * @param constantPool Constant pool to be used for this object. + * @param delta offset delta */ - public void setConstantPool( final ConstantPool constantPool ) { - this.constantPool = constantPool; + public void updateByteCodeOffset(final int delta) { + setByteCodeOffset(byteCodeOffset + delta); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,142 +23,144 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class represents a stack map attribute used for - * preverification of Java classes for the Java Platform, Micro Edition - * (Java ME). This attribute is used by the KVM - * and contained within the Code attribute of a method. See CLDC specification - * 5.3.1.2 + * This class represents a stack map attribute used for preverification of Java classes for the + * Java 2 Micro Edition (J2ME). This attribute is used by the + * KVM and contained within the Code attribute of a method. See CLDC + * specification 5.3.1.2 * - * @see Code - * @see StackMapEntry - * @see StackMapType + *
    + * StackMapTable_attribute {
    + *   u2              attribute_name_index;
    + *   u4              attribute_length;
    + *   u2              number_of_entries;
    + *   stack_map_frame entries[number_of_entries];
    + * }
    + * 
    + * + * @see Code + * @see StackMapEntry + * @see StackMapType * @LastModified: Oct 2020 */ public final class StackMap extends Attribute { - private StackMapEntry[] map; // Table of stack map entries + private StackMapEntry[] table; // Table of stack map entries + /** + * Construct object from input stream. + * + * @param nameIndex Index of name + * @param length Content length in bytes + * @param dataInput Input stream + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. + */ + StackMap(final int nameIndex, final int length, final DataInput dataInput, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (StackMapEntry[]) null, constantPool); + final int mapLength = dataInput.readUnsignedShort(); + table = new StackMapEntry[mapLength]; + for (int i = 0; i < mapLength; i++) { + table[i] = new StackMapEntry(dataInput, constantPool); + } + } /* - * @param name_index Index of name + * @param nameIndex Index of name + * * @param length Content length in bytes + * * @param map Table of stack map entries - * @param constant_pool Array of constants + * + * @param constantPool Array of constants */ - public StackMap(final int name_index, final int length, final StackMapEntry[] map, final ConstantPool constant_pool) { - super(Const.ATTR_STACK_MAP, name_index, length, constant_pool); - this.map = map; + public StackMap(final int nameIndex, final int length, final StackMapEntry[] table, final ConstantPool constantPool) { + super(Const.ATTR_STACK_MAP, nameIndex, length, constantPool); + this.table = table != null ? table : StackMapEntry.EMPTY_ARRAY; + Args.requireU2(this.table.length, "table.length"); } - /** - * Construct object from input stream. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * - * @param name_index Index of name - * @param length Content length in bytes - * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException - */ - StackMap(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) throws IOException { - this(name_index, length, (StackMapEntry[]) null, constant_pool); - final int map_length = input.readUnsignedShort(); - map = new StackMapEntry[map_length]; - for (int i = 0; i < map_length; i++) { - map[i] = new StackMapEntry(input, constant_pool); - } + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackMap(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final StackMap c = (StackMap) clone(); + c.table = new StackMapEntry[table.length]; + Arrays.setAll(c.table, i -> table[i].copy()); + c.setConstantPool(constantPool); + return c; + } /** * Dump stack map table attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); - file.writeShort(map.length); - for (final StackMapEntry entry : map) { + file.writeShort(table.length); + for (final StackMapEntry entry : table) { entry.dump(file); } } + public int getMapLength() { + return table.length; + } /** * @return Array of stack map entries */ public StackMapEntry[] getStackMap() { - return map; + return table; } - /** - * @param map Array of stack map entries + * @param table Array of stack map entries */ - public void setStackMap( final StackMapEntry[] map ) { - this.map = map; + public void setStackMap(final StackMapEntry[] table) { + this.table = table != null ? table : StackMapEntry.EMPTY_ARRAY; int len = 2; // Length of 'number_of_entries' field prior to the array of stack maps - for (final StackMapEntry element : map) { + for (final StackMapEntry element : this.table) { len += element.getMapEntrySize(); } setLength(len); } - /** * @return String representation. */ @Override public String toString() { final StringBuilder buf = new StringBuilder("StackMap("); - for (int i = 0; i < map.length; i++) { - buf.append(map[i]); - if (i < map.length - 1) { + int runningOffset = -1; // no +1 on first entry + for (int i = 0; i < table.length; i++) { + runningOffset = table[i].getByteCodeOffset() + runningOffset + 1; + buf.append(String.format("%n@%03d %s", runningOffset, table[i])); + if (i < table.length - 1) { buf.append(", "); } } buf.append(')'); return buf.toString(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final StackMap c = (StackMap) clone(); - c.map = new StackMapEntry[map.length]; - for (int i = 0; i < map.length; i++) { - c.map[i] = map[i].copy(); - } - c.setConstantPool(_constant_pool); - return c; - } - - - /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitStackMap(this); - } - - - public int getMapLength() { - return map == null ? 0 : map.length; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,143 +28,135 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This class represents the type of a local variable or item on stack - * used in the StackMap entries. + * This class represents the type of a local variable or item on stack used in the StackMap entries. * - * @see StackMapEntry - * @see StackMap - * @see Const + * @see StackMapEntry + * @see StackMap + * @see Const */ public final class StackMapType implements Cloneable { + public static final StackMapType[] EMPTY_ARRAY = {}; // must be public because BCELifier code generator writes calls to it + private byte type; private int index = -1; // Index to CONSTANT_Class or offset private ConstantPool constantPool; - - /** - * Construct object from file stream. - * @param file Input stream - * @throws IOException - */ - StackMapType(final DataInput file, final ConstantPool constant_pool) throws IOException { - this(file.readByte(), -1, constant_pool); - if (hasIndex()) { - this.index = file.readShort(); - } - this.constantPool = constant_pool; - } - - /** * @param type type tag as defined in the Constants interface * @param index index to constant pool, or byte code offset */ - public StackMapType(final byte type, final int index, final ConstantPool constant_pool) { - if ((type < Const.ITEM_Bogus) || (type > Const.ITEM_NewObject)) { - throw new IllegalArgumentException("Illegal type for StackMapType: " + type); - } - this.type = type; + public StackMapType(final byte type, final int index, final ConstantPool constantPool) { + this.type = checkType(type); this.index = index; - this.constantPool = constant_pool; + this.constantPool = constantPool; } - - public void setType( final byte t ) { - if ((t < Const.ITEM_Bogus) || (t > Const.ITEM_NewObject)) { - throw new IllegalArgumentException("Illegal type for StackMapType: " + t); + /** + * Construct object from file stream. + * + * @param file Input stream + * @throws IOException if an I/O error occurs. + */ + StackMapType(final DataInput file, final ConstantPool constantPool) throws IOException { + this(file.readByte(), -1, constantPool); + if (hasIndex()) { + this.index = file.readUnsignedShort(); } - type = t; + this.constantPool = constantPool; } - - public byte getType() { + private byte checkType(final byte type) { + if (type < Const.ITEM_Bogus || type > Const.ITEM_NewObject) { + throw new ClassFormatException("Illegal type for StackMapType: " + type); + } return type; } - - public void setIndex( final int t ) { - index = t; - } - - - /** @return index to constant pool if type == ITEM_Object, or offset - * in byte code, if type == ITEM_NewObject, and -1 otherwise + /** + * @return deep copy of this object */ - public int getIndex() { - return index; + public StackMapType copy() { + try { + return (StackMapType) clone(); + } catch (final CloneNotSupportedException e) { + // TODO should this throw? + } + return null; } - /** * Dump type entries to file. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { file.writeByte(type); if (hasIndex()) { file.writeShort(getIndex()); } } + /** + * @return Constant pool used by this object. + */ + public ConstantPool getConstantPool() { + return constantPool; + } - /** @return true, if type is either ITEM_Object or ITEM_NewObject + /** + * @return index to constant pool if type == ITEM_Object, or offset in byte code, if type == ITEM_NewObject, and -1 + * otherwise + */ + public int getIndex() { + return index; + } + + public byte getType() { + return type; + } + + /** + * @return true, if type is either ITEM_Object or ITEM_NewObject */ public boolean hasIndex() { return type == Const.ITEM_Object || type == Const.ITEM_NewObject; } - private String printIndex() { if (type == Const.ITEM_Object) { if (index < 0) { return ", class="; } return ", class=" + constantPool.constantToString(index, Const.CONSTANT_Class); - } else if (type == Const.ITEM_NewObject) { + } + if (type == Const.ITEM_NewObject) { return ", offset=" + index; - } else { - return ""; } + return ""; } - /** - * @return String representation + * @param constantPool Constant pool to be used for this object. */ - @Override - public String toString() { - return "(type=" + Const.getItemName(type) + printIndex() + ")"; + public void setConstantPool(final ConstantPool constantPool) { + this.constantPool = constantPool; } - - /** - * @return deep copy of this object - */ - public StackMapType copy() { - try { - return (StackMapType) clone(); - } catch (final CloneNotSupportedException e) { - // TODO should this throw? - } - return null; + public void setIndex(final int index) { + this.index = index; } - - /** - * @return Constant pool used by this object. - */ - public ConstantPool getConstantPool() { - return constantPool; + public void setType(final byte type) { + this.type = checkType(type); } - /** - * @param constantPool Constant pool to be used for this object. + * @return String representation */ - public void setConstantPool( final ConstantPool constantPool ) { - this.constantPool = constantPool; + @Override + public String toString() { + return "(type=" + Const.getItemName(type) + printIndex() + ")"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,58 +26,42 @@ import java.io.IOException; import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.util.Args; /** - * This class is derived from Attribute and declares this class as - * `synthetic', i.e., it needs special handling. The JVM specification - * states "A class member that does not appear in the source code must be - * marked using a Synthetic attribute." It may appear in the ClassFile - * attribute table, a field_info table or a method_info table. This class - * is intended to be instantiated from the - * Attribute.readAttribute() method. + * This class is derived from Attribute and declares this class as 'synthetic', i.e., it needs special + * handling. The JVM specification states "A class member that does not appear in the source code must be marked using a + * Synthetic attribute." It may appear in the ClassFile attribute table, a field_info table or a method_info table. This + * class is intended to be instantiated from the Attribute.readAttribute() method. * - * @see Attribute + * @see Attribute */ public final class Synthetic extends Attribute { private byte[] bytes; - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use copy() for a physical copy. - */ - public Synthetic(final Synthetic c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } - - /** - * @param name_index Index in constant pool to CONSTANT_Utf8, which - * should represent the string "Synthetic". + * @param nameIndex Index in constant pool to CONSTANT_Utf8, which should represent the string "Synthetic". * @param length Content length in bytes - should be zero. * @param bytes Attribute contents - * @param constant_pool The constant pool this attribute is associated - * with. + * @param constantPool The constant pool this attribute is associated with. */ - public Synthetic(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { - super(Const.ATTR_SYNTHETIC, name_index, length, constant_pool); + public Synthetic(final int nameIndex, final int length, final byte[] bytes, final ConstantPool constantPool) { + super(Const.ATTR_SYNTHETIC, nameIndex, Args.require0(length, "Synthetic attribute length"), constantPool); this.bytes = bytes; } - /** * Construct object from input stream. * - * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param nameIndex Index in constant pool to CONSTANT_Utf8 * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - Synthetic(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, (byte[]) null, constant_pool); + Synthetic(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (byte[]) null, constantPool); if (length > 0) { bytes = new byte[length]; input.readFully(bytes); @@ -85,35 +69,54 @@ } } + /** + * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a + * physical copy. + * + * @param c Source to copy. + */ + public Synthetic(final Synthetic c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitSynthetic(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final Synthetic c = (Synthetic) clone(); + if (bytes != null) { + c.bytes = bytes.clone(); + } + c.setConstantPool(constantPool); + return c; + } /** * Dump source file attribute to file stream in binary format. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); if (super.getLength() > 0) { file.write(bytes, 0, super.getLength()); } } - /** * @return data bytes. */ @@ -121,15 +124,13 @@ return bytes; } - /** * @param bytes */ - public void setBytes( final byte[] bytes ) { + public void setBytes(final byte[] bytes) { this.bytes = bytes; } - /** * @return String representation. */ @@ -141,19 +142,4 @@ } return buf.toString(); } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final Synthetic c = (Synthetic) clone(); - if (bytes != null) { - c.bytes = new byte[bytes.length]; - System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); - } - c.setConstantPool(_constant_pool); - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/UnknownAttributeReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,9 +22,8 @@ package com.sun.org.apache.bcel.internal.classfile; /** - * Unknown (non-standard) attributes may be read via user-defined factory - * objects that can be registered with the Attribute.addAttributeReader - * method. These factory objects should implement this interface. + * Unknown (non-standard) attributes may be read via user-defined factory objects that can be registered with the + * Attribute.addAttributeReader method. These factory objects should implement this interface. * * @see Attribute * @since 6.0 @@ -32,22 +31,20 @@ public interface UnknownAttributeReader { /** - * When this attribute reader is added via the static method Attribute.addAttributeReader, - * an attribute name is associated with it. As the class file parser parses attributes, - * it will call various AttributeReaders based on the name of the attributes it is constructing. + * When this attribute reader is added via the static method Attribute.addAttributeReader, an attribute name is + * associated with it. As the class file parser parses attributes, it will call various AttributeReaders based on the + * name of the attributes it is constructing. * - * @param name_index An index into the constant pool, indexing a ConstantUtf8 - * that represents the name of the attribute. - * @param length The length of the data contained in the attribute. This is written - * into the constant pool and should agree with what the factory expects the length to be. - * @param file This is the data input that the factory needs to read its data from. - * @param constant_pool This is the constant pool associated with the Attribute that we are constructing. + * @param nameIndex An index into the constant pool, indexing a ConstantUtf8 that represents the name of the attribute. + * @param length The length of the data contained in the attribute. This is written into the constant pool and should + * agree with what the factory expects the length to be. + * @param file This is the data input that the factory needs to read its data from. + * @param constantPool This is the constant pool associated with the Attribute that we are constructing. * - * @return The user-defined AttributeReader should take this data and use - * it to construct an attribute. In the case of errors, a null can be - * returned which will cause the parsing of the class file to fail. + * @return The user-defined AttributeReader should take this data and use it to construct an attribute. In the case of + * errors, a null can be returned which will cause the parsing of the class file to fail. * * @see Attribute#addAttributeReader(String, UnknownAttributeReader) */ - Attribute createAttribute( int name_index, int length, java.io.DataInput file, ConstantPool constant_pool ); + Attribute createAttribute(int nameIndex, int length, java.io.DataInput file, ConstantPool constantPool); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,19 +24,15 @@ import java.io.DataInput; import java.io.DataOutputStream; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; +import java.util.Arrays; import com.sun.org.apache.bcel.internal.Const; /** - * This class represents a reference to an unknown (i.e., - * application-specific) attribute of a class. It is instantiated from the - * {@link Attribute#readAttribute(java.io.DataInput, ConstantPool)} method. - * Applications that need to read in application-specific attributes should create an - * {@link UnknownAttributeReader} implementation and attach it via + * This class represents a reference to an unknown (i.e., application-specific) attribute of a class. It is instantiated + * from the {@link Attribute#readAttribute(java.io.DataInput, ConstantPool)} method. Applications that need to read in + * application-specific attributes should create an {@link UnknownAttributeReader} implementation and attach it via * {@link Attribute#addAttributeReader(String, UnknownAttributeReader)}. - * * @see Attribute * @see UnknownAttributeReader @@ -44,93 +40,87 @@ public final class Unknown extends Attribute { private byte[] bytes; - private final String name; - private static final Map unknownAttributes = new HashMap<>(); - - - /** @return array of unknown attributes, but just one for each kind. - */ - static Unknown[] getUnknownAttributes() { - final Unknown[] unknowns = new Unknown[unknownAttributes.size()]; - unknownAttributes.values().toArray(unknowns); - unknownAttributes.clear(); - return unknowns; - } - - - /** - * Initialize from another object. Note that both objects use the same - * references (shallow copy). Use clone() for a physical copy. - */ - public Unknown(final Unknown c) { - this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); - } + private final String name; /** - * Create a non-standard attribute. + * Constructs a new instance for a non-standard attribute. * - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param bytes Attribute contents - * @param constant_pool Array of constants + * @param constantPool Array of constants */ - public Unknown(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) { - super(Const.ATTR_UNKNOWN, name_index, length, constant_pool); + public Unknown(final int nameIndex, final int length, final byte[] bytes, final ConstantPool constantPool) { + super(Const.ATTR_UNKNOWN, nameIndex, length, constantPool); this.bytes = bytes; - name = ((ConstantUtf8) constant_pool.getConstant(name_index, Const.CONSTANT_Utf8)) - .getBytes(); - unknownAttributes.put(name, this); + this.name = constantPool.getConstantUtf8(nameIndex).getBytes(); } - /** - * Construct object from input stream. + * Constructs a new instance from an input stream. * - * @param name_index Index in constant pool + * @param nameIndex Index in constant pool * @param length Content length in bytes * @param input Input stream - * @param constant_pool Array of constants - * @throws IOException + * @param constantPool Array of constants + * @throws IOException if an I/O error occurs. */ - Unknown(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool) - throws IOException { - this(name_index, length, (byte[]) null, constant_pool); + Unknown(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException { + this(nameIndex, length, (byte[]) null, constantPool); if (length > 0) { bytes = new byte[length]; input.readFully(bytes); } } + /** + * Constructs a new instance from another instance. Note that both objects use the same references (shallow copy). Use clone() for a physical copy. + * + * @param unknown Source. + */ + public Unknown(final Unknown unknown) { + this(unknown.getNameIndex(), unknown.getLength(), unknown.getBytes(), unknown.getConstantPool()); + } /** - * Called by objects that are traversing the nodes of the tree implicitely - * defined by the contents of a Java class. I.e., the hierarchy of methods, - * fields, attributes, etc. spawns a tree of objects. + * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class. + * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitUnknown(this); } + /** + * @return deep copy of this attribute + */ + @Override + public Attribute copy(final ConstantPool constantPool) { + final Unknown c = (Unknown) clone(); + if (bytes != null) { + c.bytes = bytes.clone(); + } + c.setConstantPool(constantPool); + return c; + } /** - * Dump unknown bytes to file stream. + * Dumps unknown bytes to file stream. * * @param file Output file stream - * @throws IOException + * @throws IOException if an I/O error occurs. */ @Override - public void dump( final DataOutputStream file ) throws IOException { + public void dump(final DataOutputStream file) throws IOException { super.dump(file); if (super.getLength() > 0) { file.write(bytes, 0, super.getLength()); } } - /** * @return data bytes. */ @@ -138,7 +128,6 @@ return bytes; } - /** * @return name of attribute. */ @@ -147,15 +136,13 @@ return name; } - /** * @param bytes the bytes to set */ - public void setBytes( final byte[] bytes ) { + public void setBytes(final byte[] bytes) { this.bytes = bytes; } - /** * @return String representation. */ @@ -165,28 +152,13 @@ return "(Unknown attribute " + name + ")"; } String hex; - if (super.getLength() > 10) { - final byte[] tmp = new byte[10]; - System.arraycopy(bytes, 0, tmp, 0, 10); + final int limit = 10; + if (super.getLength() > limit) { + final byte[] tmp = Arrays.copyOf(bytes, limit); hex = Utility.toHexString(tmp) + "... (truncated)"; } else { hex = Utility.toHexString(bytes); } return "(Unknown attribute " + name + ": " + hex + ")"; } - - - /** - * @return deep copy of this attribute - */ - @Override - public Attribute copy( final ConstantPool _constant_pool ) { - final Unknown c = (Unknown) clone(); - if (bytes != null) { - c.bytes = new byte[bytes.length]; - System.arraycopy(bytes, 0, c.bytes, 0, bytes.length); - } - c.setConstantPool(_constant_pool); - return c; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,6 +31,7 @@ import java.io.Reader; import java.io.Writer; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.zip.GZIPInputStream; @@ -42,78 +43,167 @@ /** * Utility functions that do not really belong to any class in particular. * - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ // @since 6.0 methods are no longer final public abstract class Utility { - private static int unwrap( final ThreadLocal tl ) { - return tl.get(); - } + /** + * Decode characters into bytes. Used by decode() + */ + private static class JavaReader extends FilterReader { - private static void wrap( final ThreadLocal tl, final int value ) { - tl.set(value); + public JavaReader(final Reader in) { + super(in); + } + + @Override + public int read() throws IOException { + final int b = in.read(); + if (b != ESCAPE_CHAR) { + return b; + } + final int i = in.read(); + if (i < 0) { + return -1; + } + if (i >= '0' && i <= '9' || i >= 'a' && i <= 'f') { // Normal escape + final int j = in.read(); + if (j < 0) { + return -1; + } + final char[] tmp = {(char) i, (char) j}; + return Integer.parseInt(new String(tmp), 16); + } + return MAP_CHAR[i]; + } + + @Override + public int read(final char[] cbuf, final int off, final int len) throws IOException { + for (int i = 0; i < len; i++) { + cbuf[off + i] = (char) read(); + } + return len; + } } - /* How many chars have been consumed - * during parsing in typeSignatureToString(). - * Read by methodSignatureToString(). - * Set by side effect, but only internally. + /** + * Encode bytes into valid java identifier characters. Used by + * encode() */ - private static ThreadLocal consumed_chars = new ThreadLocal() { + private static class JavaWriter extends FilterWriter { + + public JavaWriter(final Writer out) { + super(out); + } + + @Override + public void write(final char[] cbuf, final int off, final int len) throws IOException { + for (int i = 0; i < len; i++) { + write(cbuf[off + i]); + } + } + + @Override + public void write(final int b) throws IOException { + if (isJavaIdentifierPart((char) b) && b != ESCAPE_CHAR) { + out.write(b); + } else { + out.write(ESCAPE_CHAR); // Escape character + // Special escape + if (b >= 0 && b < FREE_CHARS) { + out.write(CHAR_MAP[b]); + } else { // Normal escape + final char[] tmp = Integer.toHexString(b).toCharArray(); + if (tmp.length == 1) { + out.write('0'); + out.write(tmp[0]); + } else { + out.write(tmp[0]); + out.write(tmp[1]); + } + } + } + } + @Override - protected Integer initialValue() { - return 0; + public void write(final String str, final int off, final int len) throws IOException { + write(str.toCharArray(), off, len); } - }; + } - /* The `WIDE' instruction is used in the - * byte code to allow 16-bit wide indices - * for local variables. This opcode - * precedes an `ILOAD', e.g.. The opcode - * immediately following takes an extra - * byte which is combined with the - * following byte to form a - * 16-bit value. + /* + * How many chars have been consumed during parsing in typeSignatureToString(). Read by methodSignatureToString(). Set + * by side effect, but only internally. + */ + private static final ThreadLocal CONSUMER_CHARS = ThreadLocal.withInitial(() -> Integer.valueOf(0)); + + /* + * The 'WIDE' instruction is used in the byte code to allow 16-bit wide indices for local variables. This opcode + * precedes an 'ILOAD', e.g.. The opcode immediately following takes an extra byte which is combined with the following + * byte to form a 16-bit value. */ - private static boolean wide = false; + private static boolean wide; + + // A-Z, g-z, _, $ + private static final int FREE_CHARS = 48; + private static final int[] CHAR_MAP = new int[FREE_CHARS]; + + private static final int[] MAP_CHAR = new int[256]; // Reverse map + + private static final char ESCAPE_CHAR = '$'; + + static { + int j = 0; + for (int i = 'A'; i <= 'Z'; i++) { + CHAR_MAP[j] = i; + MAP_CHAR[i] = j; + j++; + } + for (int i = 'g'; i <= 'z'; i++) { + CHAR_MAP[j] = i; + MAP_CHAR[i] = j; + j++; + } + CHAR_MAP[j] = '$'; + MAP_CHAR['$'] = j; + j++; + CHAR_MAP[j] = '_'; + MAP_CHAR['_'] = j; + } /** - * Convert bit field of flags into string such as `static final'. + * Convert bit field of flags into string such as 'static final'. * - * @param access_flags Access flags + * @param accessFlags Access flags * @return String representation of flags */ - public static String accessToString( final int access_flags ) { - return accessToString(access_flags, false); + public static String accessToString(final int accessFlags) { + return accessToString(accessFlags, false); } - /** - * Convert bit field of flags into string such as `static final'. + * Convert bit field of flags into string such as 'static final'. * - * Special case: Classes compiled with new compilers and with the - * `ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags `ACC_SUPER' and - * `ACC_SYNCHRONIZED'. + * Special case: Classes compiled with new compilers and with the 'ACC_SUPER' flag would be said to be "synchronized". + * This is because SUN used the same value for the flags 'ACC_SUPER' and 'ACC_SYNCHRONIZED'. * - * @param access_flags Access flags - * @param for_class access flags are for class qualifiers ? + * @param accessFlags Access flags + * @param forClass access flags are for class qualifiers ? * @return String representation of flags */ - public static String accessToString( final int access_flags, final boolean for_class ) { + public static String accessToString(final int accessFlags, final boolean forClass) { final StringBuilder buf = new StringBuilder(); int p = 0; for (int i = 0; p < Const.MAX_ACC_FLAG_I; i++) { // Loop through known flags p = pow2(i); - if ((access_flags & p) != 0) { - /* Special case: Classes compiled with new compilers and with the - * `ACC_SUPER' flag would be said to be "synchronized". This is - * because SUN used the same value for the flags `ACC_SUPER' and - * `ACC_SYNCHRONIZED'. + if ((accessFlags & p) != 0) { + /* + * Special case: Classes compiled with new compilers and with the 'ACC_SUPER' flag would be said to be "synchronized". + * This is because SUN used the same value for the flags 'ACC_SUPER' and 'ACC_SYNCHRONIZED'. */ - if (for_class && ((p == Const.ACC_SUPER) || (p == Const.ACC_INTERFACE))) { + if (forClass && (p == Const.ACC_SUPER || p == Const.ACC_INTERFACE)) { continue; } buf.append(Const.getAccessName(i)).append(" "); @@ -122,42 +212,55 @@ return buf.toString().trim(); } + /** + * Convert (signed) byte to (unsigned) short value, i.e., all negative values become positive. + */ + private static short byteToShort(final byte b) { + return b < 0 ? (short) (256 + b) : (short) b; + } /** - * @param access_flags the class flags + * @param accessFlags the class flags * * @return "class" or "interface", depending on the ACC_INTERFACE flag */ - public static String classOrInterface( final int access_flags ) { - return ((access_flags & Const.ACC_INTERFACE) != 0) ? "interface" : "class"; + public static String classOrInterface(final int accessFlags) { + return (accessFlags & Const.ACC_INTERFACE) != 0 ? "interface" : "class"; + } + + /** + * @return 'flag' with bit 'i' set to 0 + */ + public static int clearBit(final int flag, final int i) { + final int bit = pow2(i); + return (flag & bit) == 0 ? flag : flag ^ bit; } + public static String codeToString(final byte[] code, final ConstantPool constantPool, final int index, final int length) { + return codeToString(code, constantPool, index, length, true); + } /** - * Disassemble a byte array of JVM byte codes starting from code line - * `index' and return the disassembled string representation. Decode only - * `num' opcodes (including their operands), use -1 if you want to - * decompile everything. + * Disassemble a byte array of JVM byte codes starting from code line 'index' and return the disassembled string + * representation. Decode only 'num' opcodes (including their operands), use -1 if you want to decompile everything. * - * @param code byte code array - * @param constant_pool Array of constants - * @param index offset in `code' array - * (number of opcodes, not bytes!) - * @param length number of opcodes to decompile, -1 for all - * @param verbose be verbose, e.g. print constant pool index + * @param code byte code array + * @param constantPool Array of constants + * @param index offset in 'code' array (number of opcodes, not bytes!) + * @param length number of opcodes to decompile, -1 for all + * @param verbose be verbose, e.g. print constant pool index * @return String representation of byte codes */ - public static String codeToString( final byte[] code, final ConstantPool constant_pool, final int index, - final int length, final boolean verbose ) { + public static String codeToString(final byte[] code, final ConstantPool constantPool, final int index, final int length, final boolean verbose) { final StringBuilder buf = new StringBuilder(code.length * 20); // Should be sufficient // CHECKSTYLE IGNORE MagicNumber try (ByteSequence stream = new ByteSequence(code)) { for (int i = 0; i < index; i++) { - codeToString(stream, constant_pool, verbose); + codeToString(stream, constantPool, verbose); } for (int i = 0; stream.available() > 0; i++) { - if ((length < 0) || (i < length)) { + if (length < 0 || i < length) { final String indices = fillup(stream.getIndex() + ":", 6, true, ' '); - buf.append(indices).append(codeToString(stream, constant_pool, verbose)).append('\n'); + buf.append(indices).append(codeToString(stream, constantPool, verbose)).append('\n'); } } } catch (final IOException e) { @@ -166,28 +269,25 @@ return buf.toString(); } - - public static String codeToString( final byte[] code, final ConstantPool constant_pool, final int index, final int length ) { - return codeToString(code, constant_pool, index, length, true); + public static String codeToString(final ByteSequence bytes, final ConstantPool constantPool) throws IOException { + return codeToString(bytes, constantPool, true); } - /** - * Disassemble a stream of byte codes and return the - * string representation. + * Disassemble a stream of byte codes and return the string representation. * - * @param bytes stream of bytes - * @param constant_pool Array of constants - * @param verbose be verbose, e.g. print constant pool index + * @param bytes stream of bytes + * @param constantPool Array of constants + * @param verbose be verbose, e.g. print constant pool index * @return String representation of byte code * * @throws IOException if a failure from reading from the bytes argument occurs */ @SuppressWarnings("fallthrough") // by design for case Const.INSTANCEOF - public static String codeToString(final ByteSequence bytes, final ConstantPool constant_pool, + public static String codeToString(final ByteSequence bytes, final ConstantPool constantPool, final boolean verbose) throws IOException { final short opcode = (short) bytes.readUnsignedByte(); - int default_offset = 0; + int defaultOffset = 0; int low; int high; int npairs; @@ -195,441 +295,612 @@ int vindex; int constant; int[] match; - int[] jump_table; - int no_pad_bytes = 0; + int[] jumpTable; + int noPadBytes = 0; int offset; final StringBuilder buf = new StringBuilder(Const.getOpcodeName(opcode)); - /* Special case: Skip (0-3) padding bytes, i.e., the - * following bytes are 4-byte-aligned + /* + * Special case: Skip (0-3) padding bytes, i.e., the following bytes are 4-byte-aligned */ - if ((opcode == Const.TABLESWITCH) || (opcode == Const.LOOKUPSWITCH)) { + if (opcode == Const.TABLESWITCH || opcode == Const.LOOKUPSWITCH) { final int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; - for (int i = 0; i < no_pad_bytes; i++) { + noPadBytes = remainder == 0 ? 0 : 4 - remainder; + for (int i = 0; i < noPadBytes; i++) { byte b; if ((b = bytes.readByte()) != 0) { - System.err.println("Warning: Padding byte != 0 in " - + Const.getOpcodeName(opcode) + ":" + b); + System.err.println("Warning: Padding byte != 0 in " + Const.getOpcodeName(opcode) + ":" + b); } } // Both cases have a field default_offset in common - default_offset = bytes.readInt(); + defaultOffset = bytes.readInt(); } switch (opcode) { - /* Table switch has variable length arguments. - */ - case Const.TABLESWITCH: - low = bytes.readInt(); - high = bytes.readInt(); - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - buf.append("\tdefault = ").append(default_offset).append(", low = ").append(low) - .append(", high = ").append(high).append("("); - jump_table = new int[high - low + 1]; - for (int i = 0; i < jump_table.length; i++) { - jump_table[i] = offset + bytes.readInt(); - buf.append(jump_table[i]); - if (i < jump_table.length - 1) { - buf.append(", "); - } - } - buf.append(")"); - break; - /* Lookup switch has variable length arguments. - */ - case Const.LOOKUPSWITCH: { - npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - match = new int[npairs]; - jump_table = new int[npairs]; - default_offset += offset; - buf.append("\tdefault = ").append(default_offset).append(", npairs = ").append( - npairs).append(" ("); - for (int i = 0; i < npairs; i++) { - match[i] = bytes.readInt(); - jump_table[i] = offset + bytes.readInt(); - buf.append("(").append(match[i]).append(", ").append(jump_table[i]).append(")"); - if (i < npairs - 1) { - buf.append(", "); - } + /* + * Table switch has variable length arguments. + */ + case Const.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + offset = bytes.getIndex() - 12 - noPadBytes - 1; + defaultOffset += offset; + buf.append("\tdefault = ").append(defaultOffset).append(", low = ").append(low).append(", high = ").append(high).append("("); + jumpTable = new int[high - low + 1]; + for (int i = 0; i < jumpTable.length; i++) { + jumpTable[i] = offset + bytes.readInt(); + buf.append(jumpTable[i]); + if (i < jumpTable.length - 1) { + buf.append(", "); } - buf.append(")"); } - break; - /* Two address bytes + offset from start of byte stream form the - * jump target - */ - case Const.GOTO: - case Const.IFEQ: - case Const.IFGE: - case Const.IFGT: - case Const.IFLE: - case Const.IFLT: - case Const.JSR: - case Const.IFNE: - case Const.IFNONNULL: - case Const.IFNULL: - case Const.IF_ACMPEQ: - case Const.IF_ACMPNE: - case Const.IF_ICMPEQ: - case Const.IF_ICMPGE: - case Const.IF_ICMPGT: - case Const.IF_ICMPLE: - case Const.IF_ICMPLT: - case Const.IF_ICMPNE: - buf.append("\t\t#").append((bytes.getIndex() - 1) + bytes.readShort()); - break; - /* 32-bit wide jumps - */ - case Const.GOTO_W: - case Const.JSR_W: - buf.append("\t\t#").append((bytes.getIndex() - 1) + bytes.readInt()); - break; - /* Index byte references local variable (register) - */ - case Const.ALOAD: - case Const.ASTORE: - case Const.DLOAD: - case Const.DSTORE: - case Const.FLOAD: - case Const.FSTORE: - case Const.ILOAD: - case Const.ISTORE: - case Const.LLOAD: - case Const.LSTORE: - case Const.RET: - if (wide) { - vindex = bytes.readUnsignedShort(); - wide = false; // Clear flag - } else { - vindex = bytes.readUnsignedByte(); + buf.append(")"); + break; + /* + * Lookup switch has variable length arguments. + */ + case Const.LOOKUPSWITCH: { + npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - noPadBytes - 1; + match = new int[npairs]; + jumpTable = new int[npairs]; + defaultOffset += offset; + buf.append("\tdefault = ").append(defaultOffset).append(", npairs = ").append(npairs).append(" ("); + for (int i = 0; i < npairs; i++) { + match[i] = bytes.readInt(); + jumpTable[i] = offset + bytes.readInt(); + buf.append("(").append(match[i]).append(", ").append(jumpTable[i]).append(")"); + if (i < npairs - 1) { + buf.append(", "); } - buf.append("\t\t%").append(vindex); - break; - /* - * Remember wide byte which is used to form a 16-bit address in the - * following instruction. Relies on that the method is called again with - * the following opcode. - */ - case Const.WIDE: - wide = true; - buf.append("\t(wide)"); - break; - /* Array of basic type. - */ - case Const.NEWARRAY: - buf.append("\t\t<").append(Const.getTypeName(bytes.readByte())).append(">"); - break; - /* Access object/class fields. - */ - case Const.GETFIELD: - case Const.GETSTATIC: - case Const.PUTFIELD: - case Const.PUTSTATIC: - index = bytes.readUnsignedShort(); - buf.append("\t\t").append( - constant_pool.constantToString(index, Const.CONSTANT_Fieldref)).append( - verbose ? " (" + index + ")" : ""); - break; - /* Operands are references to classes in constant pool - */ - case Const.NEW: - case Const.CHECKCAST: - buf.append("\t"); - //$FALL-THROUGH$ - case Const.INSTANCEOF: - index = bytes.readUnsignedShort(); - buf.append("\t<").append( - constant_pool.constantToString(index, Const.CONSTANT_Class)) - .append(">").append(verbose ? " (" + index + ")" : ""); - break; - /* Operands are references to methods in constant pool - */ - case Const.INVOKESPECIAL: - case Const.INVOKESTATIC: - index = bytes.readUnsignedShort(); - final Constant c = constant_pool.getConstant(index); - // With Java8 operand may be either a CONSTANT_Methodref - // or a CONSTANT_InterfaceMethodref. (markro) - buf.append("\t").append( - constant_pool.constantToString(index, c.getTag())) - .append(verbose ? " (" + index + ")" : ""); - break; - case Const.INVOKEVIRTUAL: - index = bytes.readUnsignedShort(); - buf.append("\t").append( - constant_pool.constantToString(index, Const.CONSTANT_Methodref)) - .append(verbose ? " (" + index + ")" : ""); - break; - case Const.INVOKEINTERFACE: - index = bytes.readUnsignedShort(); - final int nargs = bytes.readUnsignedByte(); // historical, redundant - buf.append("\t").append( - constant_pool - .constantToString(index, Const.CONSTANT_InterfaceMethodref)) - .append(verbose ? " (" + index + ")\t" : "").append(nargs).append("\t") - .append(bytes.readUnsignedByte()); // Last byte is a reserved space - break; - case Const.INVOKEDYNAMIC: - index = bytes.readUnsignedShort(); - buf.append("\t").append( - constant_pool - .constantToString(index, Const.CONSTANT_InvokeDynamic)) - .append(verbose ? " (" + index + ")\t" : "") - .append(bytes.readUnsignedByte()) // Thrid byte is a reserved space - .append(bytes.readUnsignedByte()); // Last byte is a reserved space - break; - /* Operands are references to items in constant pool - */ - case Const.LDC_W: - case Const.LDC2_W: - index = bytes.readUnsignedShort(); - buf.append("\t\t").append( - constant_pool.constantToString(index, constant_pool.getConstant(index) - .getTag())).append(verbose ? " (" + index + ")" : ""); - break; - case Const.LDC: - index = bytes.readUnsignedByte(); - buf.append("\t\t").append( - constant_pool.constantToString(index, constant_pool.getConstant(index) - .getTag())).append(verbose ? " (" + index + ")" : ""); - break; - /* Array of references. - */ - case Const.ANEWARRAY: - index = bytes.readUnsignedShort(); - buf.append("\t\t<").append( - compactClassName(constant_pool.getConstantString(index, - Const.CONSTANT_Class), false)).append(">").append( - verbose ? " (" + index + ")" : ""); - break; - /* Multidimensional array of references. - */ - case Const.MULTIANEWARRAY: { - index = bytes.readUnsignedShort(); - final int dimensions = bytes.readUnsignedByte(); - buf.append("\t<").append( - compactClassName(constant_pool.getConstantString(index, - Const.CONSTANT_Class), false)).append(">\t").append(dimensions) - .append(verbose ? " (" + index + ")" : ""); } - break; - /* Increment local variable. - */ - case Const.IINC: - if (wide) { - vindex = bytes.readUnsignedShort(); - constant = bytes.readShort(); - wide = false; - } else { - vindex = bytes.readUnsignedByte(); - constant = bytes.readByte(); - } - buf.append("\t\t%").append(vindex).append("\t").append(constant); - break; - default: - if (Const.getNoOfOperands(opcode) > 0) { - for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { - buf.append("\t\t"); - switch (Const.getOperandType(opcode, i)) { - case Const.T_BYTE: - buf.append(bytes.readByte()); - break; - case Const.T_SHORT: - buf.append(bytes.readShort()); - break; - case Const.T_INT: - buf.append(bytes.readInt()); - break; - default: // Never reached - throw new IllegalStateException("Unreachable default case reached!"); - } + buf.append(")"); + } + break; + /* + * Two address bytes + offset from start of byte stream form the jump target + */ + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.JSR: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + buf.append("\t\t#").append(bytes.getIndex() - 1 + bytes.readShort()); + break; + /* + * 32-bit wide jumps + */ + case Const.GOTO_W: + case Const.JSR_W: + buf.append("\t\t#").append(bytes.getIndex() - 1 + bytes.readInt()); + break; + /* + * Index byte references local variable (register) + */ + case Const.ALOAD: + case Const.ASTORE: + case Const.DLOAD: + case Const.DSTORE: + case Const.FLOAD: + case Const.FSTORE: + case Const.ILOAD: + case Const.ISTORE: + case Const.LLOAD: + case Const.LSTORE: + case Const.RET: + if (wide) { + vindex = bytes.readUnsignedShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("\t\t%").append(vindex); + break; + /* + * Remember wide byte which is used to form a 16-bit address in the following instruction. Relies on that the method is + * called again with the following opcode. + */ + case Const.WIDE: + wide = true; + buf.append("\t(wide)"); + break; + /* + * Array of basic type. + */ + case Const.NEWARRAY: + buf.append("\t\t<").append(Const.getTypeName(bytes.readByte())).append(">"); + break; + /* + * Access object/class fields. + */ + case Const.GETFIELD: + case Const.GETSTATIC: + case Const.PUTFIELD: + case Const.PUTSTATIC: + index = bytes.readUnsignedShort(); + buf.append("\t\t").append(constantPool.constantToString(index, Const.CONSTANT_Fieldref)).append(verbose ? " (" + index + ")" : ""); + break; + /* + * Operands are references to classes in constant pool + */ + case Const.NEW: + case Const.CHECKCAST: + buf.append("\t"); + //$FALL-THROUGH$ + case Const.INSTANCEOF: + index = bytes.readUnsignedShort(); + buf.append("\t<").append(constantPool.constantToString(index, Const.CONSTANT_Class)).append(">").append(verbose ? " (" + index + ")" : ""); + break; + /* + * Operands are references to methods in constant pool + */ + case Const.INVOKESPECIAL: + case Const.INVOKESTATIC: + index = bytes.readUnsignedShort(); + final Constant c = constantPool.getConstant(index); + // With Java8 operand may be either a CONSTANT_Methodref + // or a CONSTANT_InterfaceMethodref. (markro) + buf.append("\t").append(constantPool.constantToString(index, c.getTag())).append(verbose ? " (" + index + ")" : ""); + break; + case Const.INVOKEVIRTUAL: + index = bytes.readUnsignedShort(); + buf.append("\t").append(constantPool.constantToString(index, Const.CONSTANT_Methodref)).append(verbose ? " (" + index + ")" : ""); + break; + case Const.INVOKEINTERFACE: + index = bytes.readUnsignedShort(); + final int nargs = bytes.readUnsignedByte(); // historical, redundant + buf.append("\t").append(constantPool.constantToString(index, Const.CONSTANT_InterfaceMethodref)).append(verbose ? " (" + index + ")\t" : "") + .append(nargs).append("\t").append(bytes.readUnsignedByte()); // Last byte is a reserved space + break; + case Const.INVOKEDYNAMIC: + index = bytes.readUnsignedShort(); + buf.append("\t").append(constantPool.constantToString(index, Const.CONSTANT_InvokeDynamic)).append(verbose ? " (" + index + ")\t" : "") + .append(bytes.readUnsignedByte()) // Thrid byte is a reserved space + .append(bytes.readUnsignedByte()); // Last byte is a reserved space + break; + /* + * Operands are references to items in constant pool + */ + case Const.LDC_W: + case Const.LDC2_W: + index = bytes.readUnsignedShort(); + buf.append("\t\t").append(constantPool.constantToString(index, constantPool.getConstant(index).getTag())) + .append(verbose ? " (" + index + ")" : ""); + break; + case Const.LDC: + index = bytes.readUnsignedByte(); + buf.append("\t\t").append(constantPool.constantToString(index, constantPool.getConstant(index).getTag())) + .append(verbose ? " (" + index + ")" : ""); + break; + /* + * Array of references. + */ + case Const.ANEWARRAY: + index = bytes.readUnsignedShort(); + buf.append("\t\t<").append(compactClassName(constantPool.getConstantString(index, Const.CONSTANT_Class), false)).append(">") + .append(verbose ? " (" + index + ")" : ""); + break; + /* + * Multidimensional array of references. + */ + case Const.MULTIANEWARRAY: { + index = bytes.readUnsignedShort(); + final int dimensions = bytes.readUnsignedByte(); + buf.append("\t<").append(compactClassName(constantPool.getConstantString(index, Const.CONSTANT_Class), false)).append(">\t").append(dimensions) + .append(verbose ? " (" + index + ")" : ""); + } + break; + /* + * Increment local variable. + */ + case Const.IINC: + if (wide) { + vindex = bytes.readUnsignedShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("\t\t%").append(vindex).append("\t").append(constant); + break; + default: + if (Const.getNoOfOperands(opcode) > 0) { + for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { + buf.append("\t\t"); + switch (Const.getOperandType(opcode, i)) { + case Const.T_BYTE: + buf.append(bytes.readByte()); + break; + case Const.T_SHORT: + buf.append(bytes.readShort()); + break; + case Const.T_INT: + buf.append(bytes.readInt()); + break; + default: // Never reached + throw new IllegalStateException("Unreachable default case reached!"); } } + } } return buf.toString(); } - - public static String codeToString( final ByteSequence bytes, final ConstantPool constant_pool ) - throws IOException { - return codeToString(bytes, constant_pool, true); - } - - /** - * Shorten long class names, java/lang/String becomes - * String. + * Shorten long class names, java/lang/String becomes String. * * @param str The long class name * @return Compacted class name */ - public static String compactClassName( final String str ) { + public static String compactClassName(final String str) { return compactClassName(str, true); } - /** - * Shorten long class names, java/lang/String becomes - * java.lang.String, - * e.g.. If chopit is true the prefix java.lang - * is also removed. + * Shorten long class names, java/lang/String becomes java.lang.String, e.g.. If chopit is + * true the prefix java.lang is also removed. * * @param str The long class name * @param chopit flag that determines whether chopping is executed or not * @return Compacted class name */ - public static String compactClassName( final String str, final boolean chopit ) { + public static String compactClassName(final String str, final boolean chopit) { return compactClassName(str, "java.lang.", chopit); } - /** - * Shorten long class name str, i.e., chop off the prefix, - * if the - * class name starts with this string and the flag chopit is true. - * Slashes / are converted to dots .. + * Shorten long class name str, i.e., chop off the prefix, if the class name starts with this string + * and the flag chopit is true. Slashes / are converted to dots .. * * @param str The long class name * @param prefix The prefix the get rid off * @param chopit flag that determines whether chopping is executed or not * @return Compacted class name */ - public static String compactClassName( String str, final String prefix, final boolean chopit ) { + public static String compactClassName(String str, final String prefix, final boolean chopit) { final int len = prefix.length(); - str = str.replace('/', '.'); // Is `/' on all systems, even DOS - if (chopit) { - // If string starts with `prefix' and contains no further dots - if (str.startsWith(prefix) && (str.substring(len).indexOf('.') == -1)) { - str = str.substring(len); - } + str = pathToPackage(str); // Is '/' on all systems, even DOS + // If string starts with 'prefix' and contains no further dots + if (chopit && str.startsWith(prefix) && str.substring(len).indexOf('.') == -1) { + str = str.substring(len); } return str; } - - /** - * @return `flag' with bit `i' set to 1 - */ - public static int setBit( final int flag, final int i ) { - return flag | pow2(i); - } - - /** - * @return `flag' with bit `i' set to 0 + * Escape all occurrences of newline chars '\n', quotes \", etc. */ - public static int clearBit( final int flag, final int i ) { - final int bit = pow2(i); - return (flag & bit) == 0 ? flag : flag ^ bit; + public static String convertString(final String label) { + final char[] ch = label.toCharArray(); + final StringBuilder buf = new StringBuilder(); + for (final char element : ch) { + switch (element) { + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + case '\"': + buf.append("\\\""); + break; + case '\'': + buf.append("\\'"); + break; + case '\\': + buf.append("\\\\"); + break; + default: + buf.append(element); + break; + } + } + return buf.toString(); } - - /** - * @return true, if bit `i' in `flag' is set - */ - public static boolean isSet( final int flag, final int i ) { - return (flag & pow2(i)) != 0; + private static int countBrackets(final String brackets) { + final char[] chars = brackets.toCharArray(); + int count = 0; + boolean open = false; + for (final char c : chars) { + switch (c) { + case '[': + if (open) { + throw new IllegalArgumentException("Illegally nested brackets:" + brackets); + } + open = true; + break; + case ']': + if (!open) { + throw new IllegalArgumentException("Illegally nested brackets:" + brackets); + } + open = false; + count++; + break; + default: + // Don't care + break; + } + } + if (open) { + throw new IllegalArgumentException("Illegally nested brackets:" + brackets); + } + return count; } - /** - * Converts string containing the method return and argument types - * to a byte code method signature. + * Decode a string back to a byte array. * - * @param ret Return type of method - * @param argv Types of method arguments - * @return Byte code representation of method signature + * @param s the string to convert + * @param uncompress use gzip to uncompress the stream of bytes * - * @throws ClassFormatException if the signature is for Void + * @throws IOException if there's a gzip exception */ - public static String methodTypeToSignature( final String ret, final String[] argv ) - throws ClassFormatException { - final StringBuilder buf = new StringBuilder("("); - String str; - if (argv != null) { - for (final String element : argv) { - str = getSignature(element); - if (str.endsWith("V")) { - throw new ClassFormatException("Invalid type: " + element); - } - buf.append(str); + public static byte[] decode(final String s, final boolean uncompress) throws IOException { + byte[] bytes; + try (JavaReader jr = new JavaReader(new CharArrayReader(s.toCharArray())); ByteArrayOutputStream bos = new ByteArrayOutputStream()) { + int ch; + while ((ch = jr.read()) >= 0) { + bos.write(ch); } + bytes = bos.toByteArray(); } - str = getSignature(ret); - buf.append(")").append(str); - return buf.toString(); + if (uncompress) { + final GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); + final byte[] tmp = new byte[bytes.length * 3]; // Rough estimate + int count = 0; + int b; + while ((b = gis.read()) >= 0) { + tmp[count++] = (byte) b; + } + bytes = Arrays.copyOf(tmp, count); + } + return bytes; } - /** - * Converts argument list portion of method signature to string with all class names compacted. + * Encode byte array it into Java identifier string, i.e., a string that only contains the following characters: (a, ... + * z, A, ... Z, 0, ... 9, _, $). The encoding algorithm itself is not too clever: if the current byte's ASCII value + * already is a valid Java identifier part, leave it as it is. Otherwise it writes the escape character($) followed by: * - * @param signature Method signature - * @return String Array of argument types - * @throws ClassFormatException - */ - public static String[] methodSignatureArgumentTypes( final String signature ) - throws ClassFormatException { - return methodSignatureArgumentTypes(signature, true); - } - - - /** - * Converts argument list portion of method signature to string. + *
      + *
    • the ASCII value as a hexadecimal string, if the value is not in the range 200..247
    • + *
    • a Java identifier char not used in a lowercase hexadecimal string, if the value is in the range 200..247
    • + *
    * - * @param signature Method signature - * @param chopit flag that determines whether chopping is executed or not - * @return String Array of argument types - * @throws ClassFormatException + *

    + * This operation inflates the original byte array by roughly 40-50% + *

    + * + * @param bytes the byte array to convert + * @param compress use gzip to minimize string + * + * @throws IOException if there's a gzip exception */ - public static String[] methodSignatureArgumentTypes( final String signature, final boolean chopit ) - throws ClassFormatException { + public static String encode(byte[] bytes, final boolean compress) throws IOException { + if (compress) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream gos = new GZIPOutputStream(baos)) { + gos.write(bytes, 0, bytes.length); + gos.finish(); + bytes = baos.toByteArray(); + } + } + final CharArrayWriter caw = new CharArrayWriter(); + try (JavaWriter jw = new JavaWriter(caw)) { + for (final byte b : bytes) { + final int in = b & 0x000000ff; // Normalize to unsigned + jw.write(in); + } + } + return caw.toString(); + } + + /** + * Fillup char with up to length characters with char 'fill' and justify it left or right. + * + * @param str string to format + * @param length length of desired string + * @param leftJustify format left or right + * @param fill fill character + * @return formatted string + */ + public static String fillup(final String str, final int length, final boolean leftJustify, final char fill) { + final int len = length - str.length(); + final char[] buf = new char[Math.max(len, 0)]; + Arrays.fill(buf, fill); + if (leftJustify) { + return str + new String(buf); + } + return new String(buf) + str; + } + + /** + * Return a string for an integer justified left or right and filled up with 'fill' characters if necessary. + * + * @param i integer to format + * @param length length of desired string + * @param leftJustify format left or right + * @param fill fill character + * @return formatted int + */ + public static String format(final int i, final int length, final boolean leftJustify, final char fill) { + return fillup(Integer.toString(i), length, leftJustify, fill); + } + + /** + * WARNING: + * + * There is some nomenclature confusion through much of the BCEL code base with respect to the terms Descriptor and + * Signature. For the offical definitions see: + * + * @see Descriptors in The Java + * Virtual Machine Specification + * + * @see Signatures in The Java + * Virtual Machine Specification + * + * In brief, a descriptor is a string representing the type of a field or method. Signatures are similar, but more + * complex. Signatures are used to encode declarations written in the Java programming language that use types + * outside the type system of the Java Virtual Machine. They are used to describe the type of any class, interface, + * constructor, method or field whose declaration uses type variables or parameterized types. + * + * To parse a descriptor, call typeSignatureToString. To parse a signature, call signatureToString. + * + * Note that if the signature string is a single, non-generic item, the call to signatureToString reduces to a call + * to typeSignatureToString. Also note, that if you only wish to parse the first item in a longer signature string, + * you should call typeSignatureToString directly. + */ + + /** + * Parse Java type such as "char", or "java.lang.String[]" and return the signature in byte code format, e.g. "C" or + * "[Ljava/lang/String;" respectively. + * + * @param type Java type + * @return byte code signature + */ + public static String getSignature(String type) { + final StringBuilder buf = new StringBuilder(); + final char[] chars = type.toCharArray(); + boolean charFound = false; + boolean delim = false; + int index = -1; + loop: for (int i = 0; i < chars.length; i++) { + switch (chars[i]) { + case ' ': + case '\t': + case '\n': + case '\r': + case '\f': + if (charFound) { + delim = true; + } + break; + case '[': + if (!charFound) { + throw new IllegalArgumentException("Illegal type: " + type); + } + index = i; + break loop; + default: + charFound = true; + if (!delim) { + buf.append(chars[i]); + } + } + } + int brackets = 0; + if (index > 0) { + brackets = countBrackets(type.substring(index)); + } + type = buf.toString(); + buf.setLength(0); + for (int i = 0; i < brackets; i++) { + buf.append('['); + } + boolean found = false; + for (int i = Const.T_BOOLEAN; i <= Const.T_VOID && !found; i++) { + if (Const.getTypeName(i).equals(type)) { + found = true; + buf.append(Const.getShortTypeName(i)); + } + } + if (!found) { + buf.append('L').append(packageToPath(type)).append(';'); + } + return buf.toString(); + } + + /** + * @param ch the character to test if it's part of an identifier + * + * @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) + */ + public static boolean isJavaIdentifierPart(final char ch) { + return ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9' || ch == '_'; + } + + /** + * @return true, if bit 'i' in 'flag' is set + */ + public static boolean isSet(final int flag, final int i) { + return (flag & pow2(i)) != 0; + } + + /** + * Converts argument list portion of method signature to string with all class names compacted. + * + * @param signature Method signature + * @return String Array of argument types + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file + */ + public static String[] methodSignatureArgumentTypes(final String signature) throws ClassFormatException { + return methodSignatureArgumentTypes(signature, true); + } + + /** + * Converts argument list portion of method signature to string. + * + * @param signature Method signature + * @param chopit flag that determines whether chopping is executed or not + * @return String Array of argument types + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file + */ + public static String[] methodSignatureArgumentTypes(final String signature, final boolean chopit) throws ClassFormatException { final List vec = new ArrayList<>(); int index; try { - // Skip any type arguments to read argument declarations between `(' and `)' + // Skip any type arguments to read argument declarations between '(' and ')' index = signature.indexOf('(') + 1; if (index <= 0) { throw new ClassFormatException("Invalid method signature: " + signature); } while (signature.charAt(index) != ')') { vec.add(typeSignatureToString(signature.substring(index), chopit)); - //corrected concurrent private static field acess - index += unwrap(consumed_chars); // update position + // corrected concurrent private static field acess + index += unwrap(CONSUMER_CHARS); // update position } } catch (final StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature, e); } - return vec.toArray(new String[vec.size()]); + return vec.toArray(Const.EMPTY_STRING_ARRAY); } - /** * Converts return type portion of method signature to string with all class names compacted. * - * @param signature Method signature + * @param signature Method signature * @return String representation of method return type - * @throws ClassFormatException + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ - public static String methodSignatureReturnType( final String signature ) throws ClassFormatException { + public static String methodSignatureReturnType(final String signature) throws ClassFormatException { return methodSignatureReturnType(signature, true); } - /** * Converts return type portion of method signature to string. * - * @param signature Method signature - * @param chopit flag that determines whether chopping is executed or not + * @param signature Method signature + * @param chopit flag that determines whether chopping is executed or not * @return String representation of method return type - * @throws ClassFormatException + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ - public static String methodSignatureReturnType( final String signature, final boolean chopit ) throws ClassFormatException { + public static String methodSignatureReturnType(final String signature, final boolean chopit) throws ClassFormatException { int index; String type; try { - // Read return type after `)' + // Read return type after ')' index = signature.lastIndexOf(')') + 1; if (index <= 0) { throw new ClassFormatException("Invalid method signature: " + signature); @@ -641,81 +912,77 @@ return type; } - /** * Converts method signature to string with all class names compacted. * - * @param signature to convert - * @param name of method - * @param access flags of method + * @param signature to convert + * @param name of method + * @param access flags of method * @return Human readable signature */ - public static String methodSignatureToString( final String signature, final String name, final String access ) { + public static String methodSignatureToString(final String signature, final String name, final String access) { return methodSignatureToString(signature, name, access, true); } - /** * Converts method signature to string. * - * @param signature to convert - * @param name of method - * @param access flags of method - * @param chopit flag that determines whether chopping is executed or not + * @param signature to convert + * @param name of method + * @param access flags of method + * @param chopit flag that determines whether chopping is executed or not * @return Human readable signature */ - public static String methodSignatureToString( final String signature, final String name, final String access, final boolean chopit ) { + public static String methodSignatureToString(final String signature, final String name, final String access, final boolean chopit) { return methodSignatureToString(signature, name, access, chopit, null); } - /** - * This method converts a method signature string into a Java type declaration like - * `void main(String[])' and throws a `ClassFormatException' when the parsed - * type is invalid. - * - * @param signature Method signature - * @param name Method name - * @param access Method access rights - * @param chopit flag that determines whether chopping is executed or not - * @param vars the LocalVariableTable for the method + * This method converts a method signature string into a Java type declaration like 'void main(String[])' and throws a + * 'ClassFormatException' when the parsed type is invalid. + * + * @param signature Method signature + * @param name Method name + * @param access Method access rights + * @param chopit flag that determines whether chopping is executed or not + * @param vars the LocalVariableTable for the method * @return Java type declaration - * @throws ClassFormatException + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file */ - public static String methodSignatureToString( final String signature, final String name, - final String access, final boolean chopit, final LocalVariableTable vars ) throws ClassFormatException { + public static String methodSignatureToString(final String signature, final String name, final String access, final boolean chopit, + final LocalVariableTable vars) throws ClassFormatException { final StringBuilder buf = new StringBuilder("("); String type; int index; - int var_index = access.contains("static") ? 0 : 1; + int varIndex = access.contains("static") ? 0 : 1; try { - // Skip any type arguments to read argument declarations between `(' and `)' + // Skip any type arguments to read argument declarations between '(' and ')' index = signature.indexOf('(') + 1; if (index <= 0) { throw new ClassFormatException("Invalid method signature: " + signature); } while (signature.charAt(index) != ')') { - final String param_type = typeSignatureToString(signature.substring(index), chopit); - buf.append(param_type); + final String paramType = typeSignatureToString(signature.substring(index), chopit); + buf.append(paramType); if (vars != null) { - final LocalVariable l = vars.getLocalVariable(var_index, 0); + final LocalVariable l = vars.getLocalVariable(varIndex, 0); if (l != null) { buf.append(" ").append(l.getName()); } } else { - buf.append(" arg").append(var_index); + buf.append(" arg").append(varIndex); } - if ("double".equals(param_type) || "long".equals(param_type)) { - var_index += 2; + if ("double".equals(paramType) || "long".equals(paramType)) { + varIndex += 2; } else { - var_index++; + varIndex++; } buf.append(", "); - //corrected concurrent private static field acess - index += unwrap(consumed_chars); // update position + // corrected concurrent private static field acess + index += unwrap(CONSUMER_CHARS); // update position } index++; // update position - // Read return type after `)' + // Read return type after ')' type = typeSignatureToString(signature.substring(index), chopit); } catch (final StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature, e); @@ -725,15 +992,101 @@ buf.setLength(buf.length() - 2); } buf.append(")"); - return access + ((access.length() > 0) ? " " : "") + // May be an empty string - type + " " + name + buf.toString(); + return access + (!access.isEmpty() ? " " : "") + // May be an empty string + type + " " + name + buf.toString(); + } + + /** + * Converts string containing the method return and argument types to a byte code method signature. + * + * @param ret Return type of method + * @param argv Types of method arguments + * @return Byte code representation of method signature + * + * @throws ClassFormatException if the signature is for Void + */ + public static String methodTypeToSignature(final String ret, final String[] argv) throws ClassFormatException { + final StringBuilder buf = new StringBuilder("("); + String str; + if (argv != null) { + for (final String element : argv) { + str = getSignature(element); + if (str.endsWith("V")) { + throw new ClassFormatException("Invalid type: " + element); + } + buf.append(str); + } + } + str = getSignature(ret); + buf.append(")").append(str); + return buf.toString(); + } + + /** + * Converts '.'s to '/'s. + * + * @param name Source + * @return converted value + * @since 6.7.0 + */ + public static String packageToPath(final String name) { + return name.replace('.', '/'); } + /** + * Converts a path to a package name. + * + * @param str the source path. + * @return a package name. + * @since 6.6.0 + */ + public static String pathToPackage(final String str) { + return str.replace('/', '.'); + } - private static int pow2( final int n ) { + private static int pow2(final int n) { return 1 << n; } + public static String printArray(final Object[] obj) { + return printArray(obj, true); + } + + public static String printArray(final Object[] obj, final boolean braces) { + return printArray(obj, braces, false); + } + + public static String printArray(final Object[] obj, final boolean braces, final boolean quote) { + if (obj == null) { + return null; + } + final StringBuilder buf = new StringBuilder(); + if (braces) { + buf.append('{'); + } + for (int i = 0; i < obj.length; i++) { + if (obj[i] != null) { + buf.append(quote ? "\"" : "").append(obj[i]).append(quote ? "\"" : ""); + } else { + buf.append("null"); + } + if (i < obj.length - 1) { + buf.append(", "); + } + } + if (braces) { + buf.append('}'); + } + return buf.toString(); + } + + public static void printArray(final PrintStream out, final Object[] obj) { + out.println(printArray(obj, true)); + } + + public static void printArray(final PrintWriter out, final Object[] obj) { + out.println(printArray(obj, true)); + } /** * Replace all occurrences of old in str with new. @@ -743,20 +1096,20 @@ * @param new_ Replacement string * @return new String object */ - public static String replace( String str, final String old, final String new_ ) { + public static String replace(String str, final String old, final String new_) { int index; - int old_index; + int oldIndex; try { - if (str.contains(old)) { // `old' found in str + if (str.contains(old)) { // 'old' found in str final StringBuilder buf = new StringBuilder(); - old_index = 0; // String start offset + oldIndex = 0; // String start offset // While we have something to replace - while ((index = str.indexOf(old, old_index)) != -1) { - buf.append(str.substring(old_index, index)); // append prefix + while ((index = str.indexOf(old, oldIndex)) != -1) { + buf.append(str, oldIndex, index); // append prefix buf.append(new_); // append replacement - old_index = index + old.length(); // Skip `old'.length chars + oldIndex = index + old.length(); // Skip 'old'.length chars } - buf.append(str.substring(old_index)); // append rest of string + buf.append(str.substring(oldIndex)); // append rest of string str = buf.toString(); } } catch (final StringIndexOutOfBoundsException e) { // Should not occur @@ -765,81 +1118,69 @@ return str; } - /** - * WARNING: - * - * There is some nomenclature confusion through much of the BCEL code base with - * respect to the terms Descriptor and Signature. For the offical definitions see: - * - * @see - * Descriptors in The Java Virtual Machine Specification - * - * @see - * Signatures in The Java Virtual Machine Specification - * - * In brief, a descriptor is a string representing the type of a field or method. - * Signatures are similar, but more complex. Signatures are used to encode declarations - * written in the Java programming language that use types outside the type system of the - * Java Virtual Machine. They are used to describe the type of any class, interface, - * constructor, method or field whose declaration uses type variables or parameterized types. - * - * To parse a descriptor, call typeSignatureToString. - * To parse a signature, call signatureToString. - * - * Note that if the signature string is a single, non-generic item, the call to - * signatureToString reduces to a call to typeSignatureToString. - * Also note, that if you only wish to parse the first item in a longer signature - * string, you should call typeSignatureToString directly. + * Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload" */ + public static short searchOpcode(String name) { + name = name.toLowerCase(Locale.ENGLISH); + for (short i = 0; i < Const.OPCODE_NAMES_LENGTH; i++) { + if (Const.getOpcodeName(i).equals(name)) { + return i; + } + } + return -1; + } + /** + * @return 'flag' with bit 'i' set to 1 + */ + public static int setBit(final int flag, final int i) { + return flag | pow2(i); + } /** - * Converts a signature to a string with all class names compacted. - * Class, Method and Type signatures are supported. + * Converts a signature to a string with all class names compacted. Class, Method and Type signatures are supported. * Enum and Interface signatures are not supported. * - * @param signature signature to convert + * @param signature signature to convert * @return String containg human readable signature */ - public static String signatureToString( final String signature ) { + public static String signatureToString(final String signature) { return signatureToString(signature, true); } - /** - * Converts a signature to a string. - * Class, Method and Type signatures are supported. - * Enum and Interface signatures are not supported. + * Converts a signature to a string. Class, Method and Type signatures are supported. Enum and Interface signatures are + * not supported. * - * @param signature signature to convert - * @param chopit flag that determines whether chopping is executed or not + * @param signature signature to convert + * @param chopit flag that determines whether chopping is executed or not * @return String containg human readable signature */ - public static String signatureToString( final String signature, final boolean chopit ) { + public static String signatureToString(final String signature, final boolean chopit) { String type = ""; String typeParams = ""; int index = 0; if (signature.charAt(0) == '<') { // we have type paramters typeParams = typeParamTypesToString(signature, chopit); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } if (signature.charAt(index) == '(') { // We have a Method signature. // add types of arguments type = typeParams + typeSignaturesToString(signature.substring(index), chopit, ')'); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position // add return type type = type + typeSignatureToString(signature.substring(index), chopit); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position // ignore any throws information in the signature return type; } // Could be Class or Type... type = typeSignatureToString(signature.substring(index), chopit); - index += unwrap(consumed_chars); // update position - if ((typeParams.length() == 0) && (index == signature.length())) { + index += unwrap(CONSUMER_CHARS); // update position + if (typeParams.isEmpty() && index == signature.length()) { // We have a Type signature. return type; } @@ -850,810 +1191,372 @@ if (index < signature.length()) { typeClass.append(" implements "); typeClass.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } while (index < signature.length()) { typeClass.append(", "); typeClass.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } return typeClass.toString(); } - /** - * Converts a type parameter list signature to a string. + * Convert bytes into hexadecimal string * - * @param signature signature to convert - * @param chopit flag that determines whether chopping is executed or not - * @return String containg human readable signature + * @param bytes an array of bytes to convert to hexadecimal + * + * @return bytes as hexadecimal string, e.g. 00 fa 12 ... */ - private static String typeParamTypesToString( final String signature, final boolean chopit ) { - // The first character is guranteed to be '<' - final StringBuilder typeParams = new StringBuilder("<"); - int index = 1; // skip the '<' - // get the first TypeParameter - typeParams.append(typeParamTypeToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position - // are there more TypeParameters? - while (signature.charAt(index) != '>') { - typeParams.append(", "); - typeParams.append(typeParamTypeToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + public static String toHexString(final byte[] bytes) { + final StringBuilder buf = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + final short b = byteToShort(bytes[i]); + final String hex = Integer.toHexString(b); + if (b < 0x10) { + buf.append('0'); + } + buf.append(hex); + if (i < bytes.length - 1) { + buf.append(' '); + } } - wrap(consumed_chars, index + 1); // account for the '>' char - return typeParams.append(">").toString(); + return buf.toString(); } - /** - * Converts a type parameter signature to a string. + * Return type of method signature as a byte value as defined in Constants * - * @param signature signature to convert - * @param chopit flag that determines whether chopping is executed or not - * @return String containg human readable signature + * @param signature in format described above + * @return type of method signature + * @see Const + * + * @throws ClassFormatException if signature is not a method signature */ - private static String typeParamTypeToString( final String signature, final boolean chopit ) { - int index = signature.indexOf(':'); - if (index <= 0) { - throw new ClassFormatException("Invalid type parameter signature: " + signature); + public static byte typeOfMethodSignature(final String signature) throws ClassFormatException { + int index; + try { + if (signature.charAt(0) != '(') { + throw new ClassFormatException("Invalid method signature: " + signature); + } + index = signature.lastIndexOf(')') + 1; + return typeOfSignature(signature.substring(index)); + } catch (final StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature, e); } - // get the TypeParameter identifier - final StringBuilder typeParam = new StringBuilder(signature.substring(0, index)); - index++; // account for the ':' + } + + /** + * Return type of signature as a byte value as defined in Constants + * + * @param signature in format described above + * @return type of signature + * @see Const + * + * @throws ClassFormatException if signature isn't a known type + */ + public static byte typeOfSignature(final String signature) throws ClassFormatException { + try { + switch (signature.charAt(0)) { + case 'B': + return Const.T_BYTE; + case 'C': + return Const.T_CHAR; + case 'D': + return Const.T_DOUBLE; + case 'F': + return Const.T_FLOAT; + case 'I': + return Const.T_INT; + case 'J': + return Const.T_LONG; + case 'L': + case 'T': + return Const.T_REFERENCE; + case '[': + return Const.T_ARRAY; + case 'V': + return Const.T_VOID; + case 'Z': + return Const.T_BOOLEAN; + case 'S': + return Const.T_SHORT; + case '!': + case '+': + case '*': + return typeOfSignature(signature.substring(1)); + default: + throw new ClassFormatException("Invalid method signature: " + signature); + } + } catch (final StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature, e); + } + } + + /** + * Converts a type parameter list signature to a string. + * + * @param signature signature to convert + * @param chopit flag that determines whether chopping is executed or not + * @return String containg human readable signature + */ + private static String typeParamTypesToString(final String signature, final boolean chopit) { + // The first character is guranteed to be '<' + final StringBuilder typeParams = new StringBuilder("<"); + int index = 1; // skip the '<' + // get the first TypeParameter + typeParams.append(typeParamTypeToString(signature.substring(index), chopit)); + index += unwrap(CONSUMER_CHARS); // update position + // are there more TypeParameters? + while (signature.charAt(index) != '>') { + typeParams.append(", "); + typeParams.append(typeParamTypeToString(signature.substring(index), chopit)); + index += unwrap(CONSUMER_CHARS); // update position + } + wrap(CONSUMER_CHARS, index + 1); // account for the '>' char + return typeParams.append(">").toString(); + } + + /** + * Converts a type parameter signature to a string. + * + * @param signature signature to convert + * @param chopit flag that determines whether chopping is executed or not + * @return String containg human readable signature + */ + private static String typeParamTypeToString(final String signature, final boolean chopit) { + int index = signature.indexOf(':'); + if (index <= 0) { + throw new ClassFormatException("Invalid type parameter signature: " + signature); + } + // get the TypeParameter identifier + final StringBuilder typeParam = new StringBuilder(signature.substring(0, index)); + index++; // account for the ':' if (signature.charAt(index) != ':') { // we have a class bound typeParam.append(" extends "); typeParam.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } // look for interface bounds while (signature.charAt(index) == ':') { - index++; // skip over the ':' + index++; // skip over the ':' typeParam.append(" & "); typeParam.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } - wrap(consumed_chars, index); + wrap(CONSUMER_CHARS, index); return typeParam.toString(); } - /** * Converts a list of type signatures to a string. * - * @param signature signature to convert - * @param chopit flag that determines whether chopping is executed or not - * @param term character indicating the end of the list + * @param signature signature to convert + * @param chopit flag that determines whether chopping is executed or not + * @param term character indicating the end of the list * @return String containg human readable signature */ - private static String typeSignaturesToString( final String signature, final boolean chopit, final char term ) { + private static String typeSignaturesToString(final String signature, final boolean chopit, final char term) { // The first character will be an 'open' that matches the 'close' contained in term. final StringBuilder typeList = new StringBuilder(signature.substring(0, 1)); - int index = 1; // skip the 'open' character + int index = 1; // skip the 'open' character // get the first Type in the list if (signature.charAt(index) != term) { typeList.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } // are there more types in the list? while (signature.charAt(index) != term) { typeList.append(", "); typeList.append(typeSignatureToString(signature.substring(index), chopit)); - index += unwrap(consumed_chars); // update position + index += unwrap(CONSUMER_CHARS); // update position } - wrap(consumed_chars, index + 1); // account for the term char + wrap(CONSUMER_CHARS, index + 1); // account for the term char return typeList.append(term).toString(); } - /** * - * This method converts a type signature string into a Java type declaration such as - * `String[]' and throws a `ClassFormatException' when the parsed type is invalid. + * This method converts a type signature string into a Java type declaration such as 'String[]' and throws a + * 'ClassFormatException' when the parsed type is invalid. * - * @param signature type signature - * @param chopit flag that determines whether chopping is executed or not + * @param signature type signature + * @param chopit flag that determines whether chopping is executed or not * @return string containing human readable type signature - * @throws ClassFormatException + * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file * @since 6.4.0 */ - public static String typeSignatureToString( final String signature, final boolean chopit ) throws ClassFormatException { - //corrected concurrent private static field acess - wrap(consumed_chars, 1); // This is the default, read just one char like `B' + public static String typeSignatureToString(final String signature, final boolean chopit) throws ClassFormatException { + // corrected concurrent private static field acess + wrap(CONSUMER_CHARS, 1); // This is the default, read just one char like 'B' try { switch (signature.charAt(0)) { - case 'B': - return "byte"; - case 'C': - return "char"; - case 'D': - return "double"; - case 'F': - return "float"; - case 'I': - return "int"; - case 'J': - return "long"; - case 'T': { // TypeVariableSignature - final int index = signature.indexOf(';'); // Look for closing `;' - if (index < 0) { - throw new ClassFormatException("Invalid type variable signature: " + signature); - } - //corrected concurrent private static field acess - wrap(consumed_chars, index + 1); // "Tblabla;" `T' and `;' are removed - return compactClassName(signature.substring(1, index), chopit); + case 'B': + return "byte"; + case 'C': + return "char"; + case 'D': + return "double"; + case 'F': + return "float"; + case 'I': + return "int"; + case 'J': + return "long"; + case 'T': { // TypeVariableSignature + final int index = signature.indexOf(';'); // Look for closing ';' + if (index < 0) { + throw new ClassFormatException("Invalid type variable signature: " + signature); } - case 'L': { // Full class name - // should this be a while loop? can there be more than - // one generic clause? (markro) - int fromIndex = signature.indexOf('<'); // generic type? + // corrected concurrent private static field acess + wrap(CONSUMER_CHARS, index + 1); // "Tblabla;" 'T' and ';' are removed + return compactClassName(signature.substring(1, index), chopit); + } + case 'L': { // Full class name + // should this be a while loop? can there be more than + // one generic clause? (markro) + int fromIndex = signature.indexOf('<'); // generic type? + if (fromIndex < 0) { + fromIndex = 0; + } else { + fromIndex = signature.indexOf('>', fromIndex); if (fromIndex < 0) { - fromIndex = 0; - } else { - fromIndex = signature.indexOf('>', fromIndex); - if (fromIndex < 0) { - throw new ClassFormatException("Invalid signature: " + signature); - } - } - final int index = signature.indexOf(';', fromIndex); // Look for closing `;' - if (index < 0) { throw new ClassFormatException("Invalid signature: " + signature); } + } + final int index = signature.indexOf(';', fromIndex); // Look for closing ';' + if (index < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } - // check to see if there are any TypeArguments - final int bracketIndex = signature.substring(0, index).indexOf('<'); - if (bracketIndex < 0) { - // just a class identifier - wrap(consumed_chars, index + 1); // "Lblabla;" `L' and `;' are removed - return compactClassName(signature.substring(1, index), chopit); - } - // but make sure we are not looking past the end of the current item - fromIndex = signature.indexOf(';'); - if (fromIndex < 0) { - throw new ClassFormatException("Invalid signature: " + signature); - } - if (fromIndex < bracketIndex) { - // just a class identifier - wrap(consumed_chars, fromIndex + 1); // "Lblabla;" `L' and `;' are removed - return compactClassName(signature.substring(1, fromIndex), chopit); - } + // check to see if there are any TypeArguments + final int bracketIndex = signature.substring(0, index).indexOf('<'); + if (bracketIndex < 0) { + // just a class identifier + wrap(CONSUMER_CHARS, index + 1); // "Lblabla;" 'L' and ';' are removed + return compactClassName(signature.substring(1, index), chopit); + } + // but make sure we are not looking past the end of the current item + fromIndex = signature.indexOf(';'); + if (fromIndex < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + if (fromIndex < bracketIndex) { + // just a class identifier + wrap(CONSUMER_CHARS, fromIndex + 1); // "Lblabla;" 'L' and ';' are removed + return compactClassName(signature.substring(1, fromIndex), chopit); + } - // we have TypeArguments; build up partial result - // as we recurse for each TypeArgument - final StringBuilder type = new StringBuilder(compactClassName(signature.substring(1, bracketIndex), chopit)).append("<"); - int consumed_chars = bracketIndex + 1; // Shadows global var + // we have TypeArguments; build up partial result + // as we recurse for each TypeArgument + final StringBuilder type = new StringBuilder(compactClassName(signature.substring(1, bracketIndex), chopit)).append("<"); + int consumedChars = bracketIndex + 1; // Shadows global var + + // check for wildcards + if (signature.charAt(consumedChars) == '+') { + type.append("? extends "); + consumedChars++; + } else if (signature.charAt(consumedChars) == '-') { + type.append("? super "); + consumedChars++; + } + // get the first TypeArgument + if (signature.charAt(consumedChars) == '*') { + type.append("?"); + consumedChars++; + } else { + type.append(typeSignatureToString(signature.substring(consumedChars), chopit)); + // update our consumed count by the number of characters the for type argument + consumedChars = unwrap(Utility.CONSUMER_CHARS) + consumedChars; + wrap(Utility.CONSUMER_CHARS, consumedChars); + } + + // are there more TypeArguments? + while (signature.charAt(consumedChars) != '>') { + type.append(", "); // check for wildcards - if (signature.charAt(consumed_chars) == '+') { + if (signature.charAt(consumedChars) == '+') { type.append("? extends "); - consumed_chars++; - } else if (signature.charAt(consumed_chars) == '-') { + consumedChars++; + } else if (signature.charAt(consumedChars) == '-') { type.append("? super "); - consumed_chars++; + consumedChars++; } - - // get the first TypeArgument - if (signature.charAt(consumed_chars) == '*') { + if (signature.charAt(consumedChars) == '*') { type.append("?"); - consumed_chars++; + consumedChars++; } else { - type.append(typeSignatureToString(signature.substring(consumed_chars), chopit)); + type.append(typeSignatureToString(signature.substring(consumedChars), chopit)); // update our consumed count by the number of characters the for type argument - consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; - wrap(Utility.consumed_chars, consumed_chars); - } - - // are there more TypeArguments? - while (signature.charAt(consumed_chars) != '>') { - type.append(", "); - // check for wildcards - if (signature.charAt(consumed_chars) == '+') { - type.append("? extends "); - consumed_chars++; - } else if (signature.charAt(consumed_chars) == '-') { - type.append("? super "); - consumed_chars++; - } - if (signature.charAt(consumed_chars) == '*') { - type.append("?"); - consumed_chars++; - } else { - type.append(typeSignatureToString(signature.substring(consumed_chars), chopit)); - // update our consumed count by the number of characters the for type argument - consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; - wrap(Utility.consumed_chars, consumed_chars); - } + consumedChars = unwrap(Utility.CONSUMER_CHARS) + consumedChars; + wrap(Utility.CONSUMER_CHARS, consumedChars); } + } - // process the closing ">" - consumed_chars++; - type.append(">"); - - if (signature.charAt(consumed_chars) == '.') { - // we have a ClassTypeSignatureSuffix - type.append("."); - // convert SimpleClassTypeSignature to fake ClassTypeSignature - // and then recurse to parse it - type.append(typeSignatureToString("L" + signature.substring(consumed_chars+1), chopit)); - // update our consumed count by the number of characters the for type argument - // note that this count includes the "L" we added, but that is ok - // as it accounts for the "." we didn't consume - consumed_chars = unwrap(Utility.consumed_chars) + consumed_chars; - wrap(Utility.consumed_chars, consumed_chars); - return type.toString(); - } - if (signature.charAt(consumed_chars) != ';') { - throw new ClassFormatException("Invalid signature: " + signature); - } - wrap(Utility.consumed_chars, consumed_chars + 1); // remove final ";" + // process the closing ">" + consumedChars++; + type.append(">"); + + if (signature.charAt(consumedChars) == '.') { + // we have a ClassTypeSignatureSuffix + type.append("."); + // convert SimpleClassTypeSignature to fake ClassTypeSignature + // and then recurse to parse it + type.append(typeSignatureToString("L" + signature.substring(consumedChars + 1), chopit)); + // update our consumed count by the number of characters the for type argument + // note that this count includes the "L" we added, but that is ok + // as it accounts for the "." we didn't consume + consumedChars = unwrap(Utility.CONSUMER_CHARS) + consumedChars; + wrap(Utility.CONSUMER_CHARS, consumedChars); return type.toString(); } - case 'S': - return "short"; - case 'Z': - return "boolean"; - case '[': { // Array declaration - int n; - StringBuilder brackets; - String type; - int consumed_chars; // Shadows global var - brackets = new StringBuilder(); // Accumulate []'s - // Count opening brackets and look for optional size argument - for (n = 0; signature.charAt(n) == '['; n++) { - brackets.append("[]"); - } - consumed_chars = n; // Remember value - // The rest of the string denotes a `' - type = typeSignatureToString(signature.substring(n), chopit); - //corrected concurrent private static field acess - //Utility.consumed_chars += consumed_chars; is replaced by: - final int _temp = unwrap(Utility.consumed_chars) + consumed_chars; - wrap(Utility.consumed_chars, _temp); - return type + brackets.toString(); - } - case 'V': - return "void"; - default: - throw new ClassFormatException("Invalid signature: `" + signature + "'"); - } - } catch (final StringIndexOutOfBoundsException e) { // Should never occur - throw new ClassFormatException("Invalid signature: " + signature, e); - } - } - - - /** Parse Java type such as "char", or "java.lang.String[]" and return the - * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively. - * - * @param type Java type - * @return byte code signature - */ - public static String getSignature( String type ) { - final StringBuilder buf = new StringBuilder(); - final char[] chars = type.toCharArray(); - boolean char_found = false; - boolean delim = false; - int index = -1; - loop: for (int i = 0; i < chars.length; i++) { - switch (chars[i]) { - case ' ': - case '\t': - case '\n': - case '\r': - case '\f': - if (char_found) { - delim = true; - } - break; - case '[': - if (!char_found) { - throw new IllegalArgumentException("Illegal type: " + type); - } - index = i; - break loop; - default: - char_found = true; - if (!delim) { - buf.append(chars[i]); - } - } - } - int brackets = 0; - if (index > 0) { - brackets = countBrackets(type.substring(index)); - } - type = buf.toString(); - buf.setLength(0); - for (int i = 0; i < brackets; i++) { - buf.append('['); - } - boolean found = false; - for (int i = Const.T_BOOLEAN; (i <= Const.T_VOID) && !found; i++) { - if (Const.getTypeName(i).equals(type)) { - found = true; - buf.append(Const.getShortTypeName(i)); - } - } - if (!found) { - buf.append('L').append(type.replace('.', '/')).append(';'); - } - return buf.toString(); - } - - - private static int countBrackets( final String brackets ) { - final char[] chars = brackets.toCharArray(); - int count = 0; - boolean open = false; - for (final char c : chars) { - switch (c) { - case '[': - if (open) { - throw new IllegalArgumentException("Illegally nested brackets:" + brackets); - } - open = true; - break; - case ']': - if (!open) { - throw new IllegalArgumentException("Illegally nested brackets:" + brackets); - } - open = false; - count++; - break; - default: - // Don't care - break; - } - } - if (open) { - throw new IllegalArgumentException("Illegally nested brackets:" + brackets); - } - return count; - } - - - /** - * Return type of method signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of method signature - * @see Const - * - * @throws ClassFormatException if signature is not a method signature - */ - public static byte typeOfMethodSignature( final String signature ) throws ClassFormatException { - int index; - try { - if (signature.charAt(0) != '(') { - throw new ClassFormatException("Invalid method signature: " + signature); - } - index = signature.lastIndexOf(')') + 1; - return typeOfSignature(signature.substring(index)); - } catch (final StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature, e); - } - } - - - /** - * Return type of signature as a byte value as defined in Constants - * - * @param signature in format described above - * @return type of signature - * @see Const - * - * @throws ClassFormatException if signature isn't a known type - */ - public static byte typeOfSignature( final String signature ) throws ClassFormatException { - try { - switch (signature.charAt(0)) { - case 'B': - return Const.T_BYTE; - case 'C': - return Const.T_CHAR; - case 'D': - return Const.T_DOUBLE; - case 'F': - return Const.T_FLOAT; - case 'I': - return Const.T_INT; - case 'J': - return Const.T_LONG; - case 'L': - case 'T': - return Const.T_REFERENCE; - case '[': - return Const.T_ARRAY; - case 'V': - return Const.T_VOID; - case 'Z': - return Const.T_BOOLEAN; - case 'S': - return Const.T_SHORT; - case '!': - case '+': - case '*': - return typeOfSignature(signature.substring(1)); - default: - throw new ClassFormatException("Invalid method signature: " + signature); - } - } catch (final StringIndexOutOfBoundsException e) { - throw new ClassFormatException("Invalid method signature: " + signature, e); - } - } - - - /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload" - */ - public static short searchOpcode( String name ) { - name = name.toLowerCase(Locale.ENGLISH); - for (short i = 0; i < Const.OPCODE_NAMES_LENGTH; i++) { - if (Const.getOpcodeName(i).equals(name)) { - return i; - } - } - return -1; - } - - - /** - * Convert (signed) byte to (unsigned) short value, i.e., all negative - * values become positive. - */ - private static short byteToShort( final byte b ) { - return (b < 0) ? (short) (256 + b) : (short) b; - } - - - /** Convert bytes into hexadecimal string - * - * @param bytes an array of bytes to convert to hexadecimal - * - * @return bytes as hexadecimal string, e.g. 00 fa 12 ... - */ - public static String toHexString( final byte[] bytes ) { - final StringBuilder buf = new StringBuilder(); - for (int i = 0; i < bytes.length; i++) { - final short b = byteToShort(bytes[i]); - final String hex = Integer.toHexString(b); - if (b < 0x10) { - buf.append('0'); - } - buf.append(hex); - if (i < bytes.length - 1) { - buf.append(' '); - } - } - return buf.toString(); - } - - - /** - * Return a string for an integer justified left or right and filled up with - * `fill' characters if necessary. - * - * @param i integer to format - * @param length length of desired string - * @param left_justify format left or right - * @param fill fill character - * @return formatted int - */ - public static String format( final int i, final int length, final boolean left_justify, final char fill ) { - return fillup(Integer.toString(i), length, left_justify, fill); - } - - - /** - * Fillup char with up to length characters with char `fill' and justify it left or right. - * - * @param str string to format - * @param length length of desired string - * @param left_justify format left or right - * @param fill fill character - * @return formatted string - */ - public static String fillup( final String str, final int length, final boolean left_justify, final char fill ) { - final int len = length - str.length(); - final char[] buf = new char[(len < 0) ? 0 : len]; - for (int j = 0; j < buf.length; j++) { - buf[j] = fill; - } - if (left_justify) { - return str + new String(buf); - } - return new String(buf) + str; - } - - - static boolean equals( final byte[] a, final byte[] b ) { - int size; - if ((size = a.length) != b.length) { - return false; - } - for (int i = 0; i < size; i++) { - if (a[i] != b[i]) { - return false; - } - } - return true; - } - - - public static void printArray( final PrintStream out, final Object[] obj ) { - out.println(printArray(obj, true)); - } - - - public static void printArray( final PrintWriter out, final Object[] obj ) { - out.println(printArray(obj, true)); - } - - - public static String printArray( final Object[] obj ) { - return printArray(obj, true); - } - - - public static String printArray( final Object[] obj, final boolean braces ) { - return printArray(obj, braces, false); - } - - - public static String printArray( final Object[] obj, final boolean braces, final boolean quote ) { - if (obj == null) { - return null; - } - final StringBuilder buf = new StringBuilder(); - if (braces) { - buf.append('{'); - } - for (int i = 0; i < obj.length; i++) { - if (obj[i] != null) { - buf.append(quote ? "\"" : "").append(obj[i]).append(quote ? "\"" : ""); - } else { - buf.append("null"); - } - if (i < obj.length - 1) { - buf.append(", "); - } - } - if (braces) { - buf.append('}'); - } - return buf.toString(); - } - - - /** - * @param ch the character to test if it's part of an identifier - * - * @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) - */ - public static boolean isJavaIdentifierPart( final char ch ) { - return ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) - || ((ch >= '0') && (ch <= '9')) || (ch == '_'); - } - - - /** - * Encode byte array it into Java identifier string, i.e., a string - * that only contains the following characters: (a, ... z, A, ... Z, - * 0, ... 9, _, $). The encoding algorithm itself is not too - * clever: if the current byte's ASCII value already is a valid Java - * identifier part, leave it as it is. Otherwise it writes the - * escape character($) followed by: - * - *
      - *
    • the ASCII value as a hexadecimal string, if the value is not in the range 200..247
    • - *
    • a Java identifier char not used in a lowercase hexadecimal string, if the value is in the range 200..247
    • - *
    - * - *

    This operation inflates the original byte array by roughly 40-50%

    - * - * @param bytes the byte array to convert - * @param compress use gzip to minimize string - * - * @throws IOException if there's a gzip exception - */ - public static String encode(byte[] bytes, final boolean compress) throws IOException { - if (compress) { - try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); - GZIPOutputStream gos = new GZIPOutputStream(baos)) { - gos.write(bytes, 0, bytes.length); - bytes = baos.toByteArray(); - } - } - final CharArrayWriter caw = new CharArrayWriter(); - try (JavaWriter jw = new JavaWriter(caw)) { - for (final byte b : bytes) { - final int in = b & 0x000000ff; // Normalize to unsigned - jw.write(in); - } - } - return caw.toString(); - } - - - /** - * Decode a string back to a byte array. - * - * @param s the string to convert - * @param uncompress use gzip to uncompress the stream of bytes - * - * @throws IOException if there's a gzip exception - */ - public static byte[] decode(final String s, final boolean uncompress) throws IOException { - byte[] bytes; - try (JavaReader jr = new JavaReader(new CharArrayReader(s.toCharArray())); - ByteArrayOutputStream bos = new ByteArrayOutputStream()) { - int ch; - while ((ch = jr.read()) >= 0) { - bos.write(ch); - } - bytes = bos.toByteArray(); - } - if (uncompress) { - final GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); - final byte[] tmp = new byte[bytes.length * 3]; // Rough estimate - int count = 0; - int b; - while ((b = gis.read()) >= 0) { - tmp[count++] = (byte) b; - } - bytes = new byte[count]; - System.arraycopy(tmp, 0, bytes, 0, count); - } - return bytes; - } - - // A-Z, g-z, _, $ - private static final int FREE_CHARS = 48; - private static int[] CHAR_MAP = new int[FREE_CHARS]; - private static int[] MAP_CHAR = new int[256]; // Reverse map - private static final char ESCAPE_CHAR = '$'; - static { - int j = 0; - for (int i = 'A'; i <= 'Z'; i++) { - CHAR_MAP[j] = i; - MAP_CHAR[i] = j; - j++; - } - for (int i = 'g'; i <= 'z'; i++) { - CHAR_MAP[j] = i; - MAP_CHAR[i] = j; - j++; - } - CHAR_MAP[j] = '$'; - MAP_CHAR['$'] = j; - j++; - CHAR_MAP[j] = '_'; - MAP_CHAR['_'] = j; - } - - /** - * Decode characters into bytes. - * Used by decode() - */ - private static class JavaReader extends FilterReader { - - public JavaReader(final Reader in) { - super(in); - } - - - @Override - public int read() throws IOException { - final int b = in.read(); - if (b != ESCAPE_CHAR) { - return b; - } - final int i = in.read(); - if (i < 0) { - return -1; - } - if (((i >= '0') && (i <= '9')) || ((i >= 'a') && (i <= 'f'))) { // Normal escape - final int j = in.read(); - if (j < 0) { - return -1; + if (signature.charAt(consumedChars) != ';') { + throw new ClassFormatException("Invalid signature: " + signature); } - final char[] tmp = { - (char) i, (char) j - }; - final int s = Integer.parseInt(new String(tmp), 16); - return s; + wrap(Utility.CONSUMER_CHARS, consumedChars + 1); // remove final ";" + return type.toString(); } - return MAP_CHAR[i]; - } - - - @Override - public int read( final char[] cbuf, final int off, final int len ) throws IOException { - for (int i = 0; i < len; i++) { - cbuf[off + i] = (char) read(); - } - return len; - } - } - - /** - * Encode bytes into valid java identifier characters. - * Used by encode() - */ - private static class JavaWriter extends FilterWriter { - - public JavaWriter(final Writer out) { - super(out); - } - - - @Override - public void write( final int b ) throws IOException { - if (isJavaIdentifierPart((char) b) && (b != ESCAPE_CHAR)) { - out.write(b); - } else { - out.write(ESCAPE_CHAR); // Escape character - // Special escape - if (b >= 0 && b < FREE_CHARS) { - out.write(CHAR_MAP[b]); - } else { // Normal escape - final char[] tmp = Integer.toHexString(b).toCharArray(); - if (tmp.length == 1) { - out.write('0'); - out.write(tmp[0]); - } else { - out.write(tmp[0]); - out.write(tmp[1]); - } + case 'S': + return "short"; + case 'Z': + return "boolean"; + case '[': { // Array declaration + int n; + StringBuilder brackets; + String type; + int consumedChars; // Shadows global var + brackets = new StringBuilder(); // Accumulate []'s + // Count opening brackets and look for optional size argument + for (n = 0; signature.charAt(n) == '['; n++) { + brackets.append("[]"); } + consumedChars = n; // Remember value + // The rest of the string denotes a '' + type = typeSignatureToString(signature.substring(n), chopit); + // corrected concurrent private static field acess + // Utility.consumed_chars += consumed_chars; is replaced by: + final int temp = unwrap(Utility.CONSUMER_CHARS) + consumedChars; + wrap(Utility.CONSUMER_CHARS, temp); + return type + brackets.toString(); } - } - - - @Override - public void write( final char[] cbuf, final int off, final int len ) throws IOException { - for (int i = 0; i < len; i++) { - write(cbuf[off + i]); + case 'V': + return "void"; + default: + throw new ClassFormatException("Invalid signature: '" + signature + "'"); } - } - - - @Override - public void write( final String str, final int off, final int len ) throws IOException { - write(str.toCharArray(), off, len); + } catch (final StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid signature: " + signature, e); } } + private static int unwrap(final ThreadLocal tl) { + return tl.get(); + } - /** - * Escape all occurences of newline chars '\n', quotes \", etc. - */ - public static String convertString( final String label ) { - final char[] ch = label.toCharArray(); - final StringBuilder buf = new StringBuilder(); - for (final char element : ch) { - switch (element) { - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - case '\"': - buf.append("\\\""); - break; - case '\'': - buf.append("\\'"); - break; - case '\\': - buf.append("\\\\"); - break; - default: - buf.append(element); - break; - } - } - return buf.toString(); + private static void wrap(final ThreadLocal tl, final int value) { + tl.set(value); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Visitor.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,13 +22,30 @@ package com.sun.org.apache.bcel.internal.classfile; /** - * Interface to make use of the Visitor pattern programming style. I.e. a class - * that implements this interface can traverse the contents of a Java class just - * by calling the `accept' method which all classes have. - * + * Interface to make use of the Visitor pattern programming style. I.e. a class that implements this interface can + * traverse the contents of a Java class just by calling the 'accept' method which all classes have. */ -public interface Visitor -{ +public interface Visitor { + /** + * @since 6.0 + */ + void visitAnnotation(Annotations obj); + + /** + * @since 6.0 + */ + void visitAnnotationDefault(AnnotationDefault obj); + + /** + * @since 6.0 + */ + void visitAnnotationEntry(AnnotationEntry obj); + + /** + * @since 6.0 + */ + void visitBootstrapMethods(BootstrapMethods obj); + void visitCode(Code obj); void visitCodeException(CodeException obj); @@ -37,6 +54,13 @@ void visitConstantDouble(ConstantDouble obj); + /** + * @since 6.3 + */ + default void visitConstantDynamic(final ConstantDynamic constantDynamic) { + // empty + } + void visitConstantFieldref(ConstantFieldref obj); void visitConstantFloat(ConstantFloat obj); @@ -49,10 +73,30 @@ void visitConstantLong(ConstantLong obj); + /** + * @since 6.0 + */ + void visitConstantMethodHandle(ConstantMethodHandle obj); + void visitConstantMethodref(ConstantMethodref obj); + /** + * @since 6.0 + */ + void visitConstantMethodType(ConstantMethodType obj); + + /** + * @since 6.1 + */ + void visitConstantModule(ConstantModule constantModule); + void visitConstantNameAndType(ConstantNameAndType obj); + /** + * @since 6.1 + */ + void visitConstantPackage(ConstantPackage constantPackage); + void visitConstantPool(ConstantPool obj); void visitConstantString(ConstantString obj); @@ -63,6 +107,11 @@ void visitDeprecated(Deprecated obj); + /** + * @since 6.0 + */ + void visitEnclosingMethod(EnclosingMethod obj); + void visitExceptionTable(ExceptionTable obj); void visitField(Field obj); @@ -81,59 +130,12 @@ void visitLocalVariableTable(LocalVariableTable obj); - void visitMethod(Method obj); - - void visitSignature(Signature obj); - - void visitSourceFile(SourceFile obj); - - void visitSynthetic(Synthetic obj); - - void visitUnknown(Unknown obj); - - void visitStackMap(StackMap obj); - - void visitStackMapEntry(StackMapEntry obj); - - /** - * @since 6.0 - */ - void visitAnnotation(Annotations obj); - - /** - * @since 6.0 - */ - void visitParameterAnnotation(ParameterAnnotations obj); - - /** - * @since 6.0 - */ - void visitAnnotationEntry(AnnotationEntry obj); - - /** - * @since 6.0 - */ - void visitAnnotationDefault(AnnotationDefault obj); - /** * @since 6.0 */ void visitLocalVariableTypeTable(LocalVariableTypeTable obj); - /** - * @since 6.0 - */ - void visitEnclosingMethod(EnclosingMethod obj); - - /** - * @since 6.0 - */ - void visitBootstrapMethods(BootstrapMethods obj); - - /** - * @since 6.0 - */ - void visitMethodParameters(MethodParameters obj); + void visitMethod(Method obj); /** * @since 6.4.0 @@ -145,34 +147,7 @@ /** * @since 6.0 */ - void visitConstantMethodType(ConstantMethodType obj); - - /** - * @since 6.0 - */ - void visitConstantMethodHandle(ConstantMethodHandle obj); - - /** - * @since 6.0 - */ - void visitParameterAnnotationEntry(ParameterAnnotationEntry obj); - - /** - * @since 6.1 - */ - void visitConstantPackage(ConstantPackage constantPackage); - - /** - * @since 6.1 - */ - void visitConstantModule(ConstantModule constantModule); - - /** - * @since 6.3 - */ - default void visitConstantDynamic(final ConstantDynamic constantDynamic) { - // empty - } + void visitMethodParameters(MethodParameters obj); /** * @since 6.4.0 @@ -184,14 +159,14 @@ /** * @since 6.4.0 */ - default void visitModuleRequires(final ModuleRequires constantModule) { + default void visitModuleExports(final ModuleExports constantModule) { // empty } /** * @since 6.4.0 */ - default void visitModuleExports(final ModuleExports constantModule) { + default void visitModuleMainClass(final ModuleMainClass obj) { // empty } @@ -205,21 +180,21 @@ /** * @since 6.4.0 */ - default void visitModuleProvides(final ModuleProvides constantModule) { + default void visitModulePackages(final ModulePackages constantModule) { // empty } /** * @since 6.4.0 */ - default void visitModulePackages(final ModulePackages constantModule) { + default void visitModuleProvides(final ModuleProvides constantModule) { // empty } /** * @since 6.4.0 */ - default void visitModuleMainClass(final ModuleMainClass obj) { + default void visitModuleRequires(final ModuleRequires constantModule) { // empty } @@ -236,4 +211,26 @@ default void visitNestMembers(final NestMembers obj) { // empty } + + /** + * @since 6.0 + */ + void visitParameterAnnotation(ParameterAnnotations obj); + + /** + * @since 6.0 + */ + void visitParameterAnnotationEntry(ParameterAnnotationEntry obj); + + void visitSignature(Signature obj); + + void visitSourceFile(SourceFile obj); + + void visitStackMap(StackMap obj); + + void visitStackMapEntry(StackMapEntry obj); + + void visitSynthetic(Synthetic obj); + + void visitUnknown(Unknown obj); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Const.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,2416 +26,3218 @@ * Constants for the project, mostly defined in the JVM specification. * * @since 6.0 (intended to replace the Constants interface) - * @LastModified: May 2021 + * @LastModified: May 2023 */ public final class Const { - /** - * Java class file format Magic number (0xCAFEBABE) - * - * @see - * The ClassFile Structure in The Java Virtual Machine Specification - */ - public static final int JVM_CLASSFILE_MAGIC = 0xCAFEBABE; - - /** Major version number of class files for Java 1.1. - * @see #MINOR_1_1 - * */ - public static final short MAJOR_1_1 = 45; - - /** Minor version number of class files for Java 1.1. - * @see #MAJOR_1_1 - * */ - public static final short MINOR_1_1 = 3; - - /** Major version number of class files for Java 1.2. - * @see #MINOR_1_2 - * */ - public static final short MAJOR_1_2 = 46; - - /** Minor version number of class files for Java 1.2. - * @see #MAJOR_1_2 - * */ - public static final short MINOR_1_2 = 0; - - /** Major version number of class files for Java 1.2. - * @see #MINOR_1_2 - * */ - public static final short MAJOR_1_3 = 47; - - /** Minor version number of class files for Java 1.3. - * @see #MAJOR_1_3 - * */ - public static final short MINOR_1_3 = 0; - - /** Major version number of class files for Java 1.3. - * @see #MINOR_1_3 - * */ - public static final short MAJOR_1_4 = 48; - - /** Minor version number of class files for Java 1.4. - * @see #MAJOR_1_4 - * */ - public static final short MINOR_1_4 = 0; - - /** Major version number of class files for Java 1.4. - * @see #MINOR_1_4 - * */ - public static final short MAJOR_1_5 = 49; - - /** Minor version number of class files for Java 1.5. - * @see #MAJOR_1_5 - * */ - public static final short MINOR_1_5 = 0; - - /** Major version number of class files for Java 1.6. - * @see #MINOR_1_6 - * */ - public static final short MAJOR_1_6 = 50; - - /** Minor version number of class files for Java 1.6. - * @see #MAJOR_1_6 - * */ - public static final short MINOR_1_6 = 0; - - /** Major version number of class files for Java 1.7. - * @see #MINOR_1_7 - * */ - public static final short MAJOR_1_7 = 51; - - /** Minor version number of class files for Java 1.7. - * @see #MAJOR_1_7 - * */ - public static final short MINOR_1_7 = 0; - - /** Major version number of class files for Java 1.8. - * @see #MINOR_1_8 - * */ - public static final short MAJOR_1_8 = 52; - - /** Minor version number of class files for Java 1.8. - * @see #MAJOR_1_8 - * */ - public static final short MINOR_1_8 = 0; - - /** Major version number of class files for Java 9. - * @see #MINOR_9 - * */ - public static final short MAJOR_9 = 53; - - /** Minor version number of class files for Java 9. - * @see #MAJOR_9 - * */ - public static final short MINOR_9 = 0; - - /** - * @deprecated Use {@link #MAJOR_9} instead - */ - @Deprecated - public static final short MAJOR_1_9 = MAJOR_9; - - /** - * @deprecated Use {@link #MINOR_9} instead - */ - @Deprecated - public static final short MINOR_1_9 = MINOR_9; - - /** Major version number of class files for Java 10. - * @see #MINOR_10 - * */ - public static final short MAJOR_10 = 54; - - /** Minor version number of class files for Java 10. - * @see #MAJOR_10 - * */ - public static final short MINOR_10 = 0; - - /** Major version number of class files for Java 11. - * @see #MINOR_11 - * */ - public static final short MAJOR_11 = 55; - - /** Minor version number of class files for Java 11. - * @see #MAJOR_11 - * */ - public static final short MINOR_11 = 0; - - /** Major version number of class files for Java 12. - * @see #MINOR_12 - * */ - public static final short MAJOR_12 = 56; - - /** Minor version number of class files for Java 12. - * @see #MAJOR_12 - * */ - public static final short MINOR_12 = 0; - - /** Major version number of class files for Java 13. - * @see #MINOR_13 - * */ - public static final short MAJOR_13 = 57; - - /** Minor version number of class files for Java 13. - * @see #MAJOR_13 - * */ - public static final short MINOR_13 = 0; - - /** Major version number of class files for Java 14. - * @see #MINOR_14 - * @since 6.4.0 - * */ - public static final short MAJOR_14 = 58; - - /** Minor version number of class files for Java 14. - * @see #MAJOR_14 - * @since 6.4.0 - * */ - public static final short MINOR_14 = 0; - - /** Default major version number. Class file is for Java 1.1. - * @see #MAJOR_1_1 - * */ - public static final short MAJOR = MAJOR_1_1; - - /** Default major version number. Class file is for Java 1.1. - * @see #MAJOR_1_1 - * */ - public static final short MINOR = MINOR_1_1; - - /** Maximum value for an unsigned short. - */ - public static final int MAX_SHORT = 65535; // 2^16 - 1 - - /** Maximum value for an unsigned byte. - */ - public static final int MAX_BYTE = 255; // 2^8 - 1 - - /** One of the access flags for fields, methods, or classes. - * - * @see - * Flag definitions for Classes in the Java Virtual Machine Specification (Java SE 9 Edition). - * @see - * Flag definitions for Fields in the Java Virtual Machine Specification (Java SE 9 Edition). - * @see - * Flag definitions for Methods in the Java Virtual Machine Specification (Java SE 9 Edition). - * @see - * Flag definitions for Inner Classes in the Java Virtual Machine Specification (Java SE 9 Edition). - */ - public static final short ACC_PUBLIC = 0x0001; - - /** One of the access flags for fields, methods, or classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_PRIVATE = 0x0002; - - /** One of the access flags for fields, methods, or classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_PROTECTED = 0x0004; - - /** One of the access flags for fields, methods, or classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_STATIC = 0x0008; - - /** One of the access flags for fields, methods, or classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_FINAL = 0x0010; - - /** One of the access flags for the Module attribute. - * @see #ACC_PUBLIC - */ - public static final short ACC_OPEN = 0x0020; - - /** One of the access flags for classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_SUPER = 0x0020; - - /** One of the access flags for methods. - * @see #ACC_PUBLIC - */ - public static final short ACC_SYNCHRONIZED = 0x0020; - - /** One of the access flags for the Module attribute. - * @see #ACC_PUBLIC - */ - public static final short ACC_TRANSITIVE = 0x0020; - - /** One of the access flags for methods. - * @see #ACC_PUBLIC - */ - public static final short ACC_BRIDGE = 0x0040; - - /** One of the access flags for the Module attribute. - * @see #ACC_PUBLIC - */ - public static final short ACC_STATIC_PHASE = 0x0040; - - /** One of the access flags for fields. - * @see #ACC_PUBLIC - */ - public static final short ACC_VOLATILE = 0x0040; - - /** One of the access flags for fields. - * @see #ACC_PUBLIC - */ - public static final short ACC_TRANSIENT = 0x0080; - - /** One of the access flags for methods. - * @see #ACC_PUBLIC - */ - public static final short ACC_VARARGS = 0x0080; - - /** One of the access flags for methods. - * @see #ACC_PUBLIC - */ - public static final short ACC_NATIVE = 0x0100; - - /** One of the access flags for classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_INTERFACE = 0x0200; - - /** One of the access flags for methods or classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_ABSTRACT = 0x0400; - - /** One of the access flags for methods. - * @see #ACC_PUBLIC - */ - public static final short ACC_STRICT = 0x0800; - - /** One of the access flags for fields, methods, classes, MethodParameter attribute, or Module attribute. - * @see #ACC_PUBLIC - */ - public static final short ACC_SYNTHETIC = 0x1000; - - /** One of the access flags for classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_ANNOTATION = 0x2000; - - /** One of the access flags for fields or classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_ENUM = 0x4000; - - // Applies to classes compiled by new compilers only - /** One of the access flags for MethodParameter or Module attributes. - * @see #ACC_PUBLIC - */ - public static final short ACC_MANDATED = (short) 0x8000; - - /** One of the access flags for classes. - * @see #ACC_PUBLIC - */ - public static final short ACC_MODULE = (short) 0x8000; - - /** One of the access flags for fields, methods, or classes. - * @see #ACC_PUBLIC - * @deprecated Use {@link #MAX_ACC_FLAG_I} - */ - @Deprecated - public static final short MAX_ACC_FLAG = ACC_ENUM; - - /** One of the access flags for fields, methods, or classes. - * ACC_MODULE is negative as a short. - * @see #ACC_PUBLIC - * @since 6.4.0 - */ - public static final int MAX_ACC_FLAG_I = 0x8000; // ACC_MODULE is negative as a short - - // Note that do to overloading: - // 'synchronized' is for methods, might be 'open' (if Module), 'super' (if class), or 'transitive' (if Module). - // 'volatile' is for fields, might be 'bridge' (if method) or 'static_phase' (if Module) - // 'transient' is for fields, might be 'varargs' (if method) - // 'module' is for classes, might be 'mandated' (if Module or MethodParameters) - /** - * The names of the access flags. - */ - private static final String[] ACCESS_NAMES = { - "public", "private", "protected", "static", "final", "synchronized", - "volatile", "transient", "native", "interface", "abstract", "strictfp", - "synthetic", "annotation", "enum", "module" - }; - - /** @since 6.0 */ - public static final int ACCESS_NAMES_LENGTH = ACCESS_NAMES.length; - - /** - * @param index - * @return the ACCESS_NAMES entry at the given index - * @since 6.0 - */ - public static String getAccessName(final int index) { - return ACCESS_NAMES[index]; - } - - /* - * The description of the constant pool is at: - * http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 - * References below are to the individual sections - */ - - /** - * Marks a constant pool entry as type UTF-8. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Utf8 = 1; - - /** - * Marks a constant pool entry as type Integer. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Integer = 3; - - /** - * Marks a constant pool entry as type Float. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Float = 4; - - /** - * Marks a constant pool entry as type Long. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Long = 5; - - /** - * Marks a constant pool entry as type Double. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Double = 6; - - /** - * Marks a constant pool entry as a Class - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Class = 7; - - /** - * Marks a constant pool entry as a Field Reference. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_Fieldref = 9; - - /** - * Marks a constant pool entry as type String - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_String = 8; - - /** Marks a constant pool entry as a Method Reference. - * @see - * The Constant Pool in The Java Virtual Machine Specification */ - public static final byte CONSTANT_Methodref = 10; - - /** - * Marks a constant pool entry as an Interface Method Reference. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_InterfaceMethodref = 11; - - /** Marks a constant pool entry as a name and type. - * @see - * The Constant Pool in The Java Virtual Machine Specification */ - public static final byte CONSTANT_NameAndType = 12; - - /** - * Marks a constant pool entry as a Method Handle. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_MethodHandle = 15; - - /** - * Marks a constant pool entry as a Method Type. - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_MethodType = 16; - - /** - * Marks a constant pool entry as dynamically computed. - * @see - * Change request for JEP 309 - * @since 6.3 - */ - public static final byte CONSTANT_Dynamic = 17; - - /** - * Marks a constant pool entry as an Invoke Dynamic - * @see - * The Constant Pool in The Java Virtual Machine Specification - */ - public static final byte CONSTANT_InvokeDynamic = 18; - - /** - * Marks a constant pool entry as a Module Reference. - * @see - * The Constant Pool in The Java Virtual Machine Specification - * @since 6.1 - */ - public static final byte CONSTANT_Module = 19; - - /** - * Marks a constant pool entry as a Package Reference. - * @see - * The Constant Pool in The Java Virtual Machine Specification - * @since 6.1 - */ - public static final byte CONSTANT_Package = 20; - - /** - * The names of the types of entries in a constant pool. - * Use getConstantName instead - */ - private static final String[] CONSTANT_NAMES = { - "", "CONSTANT_Utf8", "", "CONSTANT_Integer", - "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", - "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", - "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref", - "CONSTANT_NameAndType", "", "", "CONSTANT_MethodHandle", - "CONSTANT_MethodType", "CONSTANT_Dynamic", "CONSTANT_InvokeDynamic", - "CONSTANT_Module", "CONSTANT_Package"}; - - /** - * - * @param index - * @return the CONSTANT_NAMES entry at the given index - * @since 6.0 - */ - public static String getConstantName(final int index) { - return CONSTANT_NAMES[index]; - } - - /** The name of the static initializer, also called "class - * initialization method" or "interface initialization - * method". This is "<clinit>". - */ - public static final String STATIC_INITIALIZER_NAME = ""; - - /** The name of every constructor method in a class, also called - * "instance initialization method". This is "<init>". - */ - public static final String CONSTRUCTOR_NAME = ""; - - /** - * The names of the interfaces implemented by arrays - */ - private static final String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"}; - - /** - * @since 6.0 - */ - public static Iterable getInterfacesImplementedByArrays() { - return Collections.unmodifiableList(Arrays.asList(INTERFACES_IMPLEMENTED_BY_ARRAYS)); - } - - /** - * Maximum Constant Pool entries. - * One of the limitations of the Java Virtual Machine. - * @see - * The Java Virtual Machine Specification, Java SE 8 Edition, page 330, chapter 4.11. - */ - public static final int MAX_CP_ENTRIES = 65535; - - /** - * Maximum code size (plus one; the code size must be LESS than this) - * One of the limitations of the Java Virtual Machine. - * Note vmspec2 page 152 ("Limitations") says: - * "The amount of code per non-native, non-abstract method is limited to 65536 bytes by - * the sizes of the indices in the exception_table of the Code attribute (4.7.3), - * in the LineNumberTable attribute (4.7.8), and in the LocalVariableTable attribute (4.7.9)." - * However this should be taken as an upper limit rather than the defined maximum. - * On page 134 (4.8.1 Static Constants) of the same spec, it says: - * "The value of the code_length item must be less than 65536." - * The entry in the Limitations section has been removed from later versions of the spec; - * it is not present in the Java SE 8 edition. - * - * @see - * The Java Virtual Machine Specification, Java SE 8 Edition, page 104, chapter 4.7. - */ - public static final int MAX_CODE_SIZE = 65536; //bytes - - /** - * The maximum number of dimensions in an array ({@value}). - * One of the limitations of the Java Virtual Machine. - * - * @see - * Field Descriptors in The Java Virtual Machine Specification - */ - public static final int MAX_ARRAY_DIMENSIONS = 255; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short NOP = 0; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ACONST_NULL = 1; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_M1 = 2; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_0 = 3; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_1 = 4; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_2 = 5; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_3 = 6; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_4 = 7; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ICONST_5 = 8; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LCONST_0 = 9; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LCONST_1 = 10; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FCONST_0 = 11; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FCONST_1 = 12; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FCONST_2 = 13; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DCONST_0 = 14; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DCONST_1 = 15; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short BIPUSH = 16; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short SIPUSH = 17; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LDC = 18; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LDC_W = 19; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LDC2_W = 20; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ILOAD = 21; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LLOAD = 22; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FLOAD = 23; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DLOAD = 24; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ALOAD = 25; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ILOAD_0 = 26; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ILOAD_1 = 27; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ILOAD_2 = 28; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ILOAD_3 = 29; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LLOAD_0 = 30; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LLOAD_1 = 31; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LLOAD_2 = 32; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LLOAD_3 = 33; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FLOAD_0 = 34; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FLOAD_1 = 35; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FLOAD_2 = 36; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FLOAD_3 = 37; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DLOAD_0 = 38; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DLOAD_1 = 39; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DLOAD_2 = 40; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DLOAD_3 = 41; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ALOAD_0 = 42; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ALOAD_1 = 43; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ALOAD_2 = 44; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ALOAD_3 = 45; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IALOAD = 46; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LALOAD = 47; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FALOAD = 48; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DALOAD = 49; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short AALOAD = 50; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short BALOAD = 51; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short CALOAD = 52; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short SALOAD = 53; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISTORE = 54; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSTORE = 55; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FSTORE = 56; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DSTORE = 57; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ASTORE = 58; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISTORE_0 = 59; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISTORE_1 = 60; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISTORE_2 = 61; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISTORE_3 = 62; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSTORE_0 = 63; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSTORE_1 = 64; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSTORE_2 = 65; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSTORE_3 = 66; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FSTORE_0 = 67; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FSTORE_1 = 68; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FSTORE_2 = 69; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FSTORE_3 = 70; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DSTORE_0 = 71; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DSTORE_1 = 72; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DSTORE_2 = 73; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DSTORE_3 = 74; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ASTORE_0 = 75; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ASTORE_1 = 76; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ASTORE_2 = 77; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ASTORE_3 = 78; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IASTORE = 79; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LASTORE = 80; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FASTORE = 81; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DASTORE = 82; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short AASTORE = 83; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short BASTORE = 84; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short CASTORE = 85; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short SASTORE = 86; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short POP = 87; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short POP2 = 88; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DUP = 89; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DUP_X1 = 90; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DUP_X2 = 91; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DUP2 = 92; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DUP2_X1 = 93; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DUP2_X2 = 94; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short SWAP = 95; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IADD = 96; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LADD = 97; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FADD = 98; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DADD = 99; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISUB = 100; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSUB = 101; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FSUB = 102; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DSUB = 103; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IMUL = 104; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LMUL = 105; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FMUL = 106; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DMUL = 107; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IDIV = 108; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LDIV = 109; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FDIV = 110; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DDIV = 111; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IREM = 112; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LREM = 113; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FREM = 114; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DREM = 115; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INEG = 116; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LNEG = 117; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FNEG = 118; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DNEG = 119; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISHL = 120; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSHL = 121; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ISHR = 122; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LSHR = 123; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IUSHR = 124; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LUSHR = 125; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IAND = 126; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LAND = 127; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IOR = 128; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LOR = 129; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IXOR = 130; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LXOR = 131; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IINC = 132; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short I2L = 133; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short I2F = 134; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short I2D = 135; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short L2I = 136; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short L2F = 137; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short L2D = 138; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short F2I = 139; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short F2L = 140; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short F2D = 141; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short D2I = 142; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short D2L = 143; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short D2F = 144; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short I2B = 145; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INT2BYTE = 145; // Old notation - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short I2C = 146; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INT2CHAR = 146; // Old notation - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short I2S = 147; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INT2SHORT = 147; // Old notation - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LCMP = 148; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FCMPL = 149; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FCMPG = 150; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DCMPL = 151; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DCMPG = 152; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFEQ = 153; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFNE = 154; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFLT = 155; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFGE = 156; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFGT = 157; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFLE = 158; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ICMPEQ = 159; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ICMPNE = 160; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ICMPLT = 161; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ICMPGE = 162; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ICMPGT = 163; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ICMPLE = 164; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ACMPEQ = 165; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IF_ACMPNE = 166; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short GOTO = 167; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short JSR = 168; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short RET = 169; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short TABLESWITCH = 170; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LOOKUPSWITCH = 171; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IRETURN = 172; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short LRETURN = 173; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short FRETURN = 174; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short DRETURN = 175; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ARETURN = 176; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short RETURN = 177; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short GETSTATIC = 178; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short PUTSTATIC = 179; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short GETFIELD = 180; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short PUTFIELD = 181; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INVOKEVIRTUAL = 182; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INVOKESPECIAL = 183; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INVOKESTATIC = 184; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INVOKEINTERFACE = 185; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INVOKEDYNAMIC = 186; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short NEW = 187; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short NEWARRAY = 188; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ANEWARRAY = 189; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ARRAYLENGTH = 190; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short ATHROW = 191; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short CHECKCAST = 192; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short INSTANCEOF = 193; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short MONITORENTER = 194; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short MONITOREXIT = 195; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short WIDE = 196; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short MULTIANEWARRAY = 197; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFNULL = 198; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short IFNONNULL = 199; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short GOTO_W = 200; - - /** Java VM opcode. - * @see - * Opcode definitions in The Java Virtual Machine Specification */ - public static final short JSR_W = 201; - - /** JVM internal opcode. - * @see - * Reserved opcodes in the Java Virtual Machine Specification */ - public static final short BREAKPOINT = 202; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short LDC_QUICK = 203; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short LDC_W_QUICK = 204; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short LDC2_W_QUICK = 205; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short GETFIELD_QUICK = 206; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short PUTFIELD_QUICK = 207; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short GETFIELD2_QUICK = 208; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short PUTFIELD2_QUICK = 209; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short GETSTATIC_QUICK = 210; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short PUTSTATIC_QUICK = 211; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short GETSTATIC2_QUICK = 212; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short PUTSTATIC2_QUICK = 213; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKEVIRTUAL_QUICK = 214; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKENONVIRTUAL_QUICK = 215; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKESUPER_QUICK = 216; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKESTATIC_QUICK = 217; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKEINTERFACE_QUICK = 218; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKEVIRTUALOBJECT_QUICK = 219; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short NEW_QUICK = 221; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short ANEWARRAY_QUICK = 222; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short MULTIANEWARRAY_QUICK = 223; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short CHECKCAST_QUICK = 224; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INSTANCEOF_QUICK = 225; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short INVOKEVIRTUAL_QUICK_W = 226; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short GETFIELD_QUICK_W = 227; - - /** JVM internal opcode. - * @see - * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) - * @see - * Why the _quick opcodes were removed from the second version of the Java Virtual Machine Specification. */ - public static final short PUTFIELD_QUICK_W = 228; - - /** JVM internal opcode. - * @see - * Reserved opcodes in the Java Virtual Machine Specification */ - public static final short IMPDEP1 = 254; - - /** JVM internal opcode. - * @see - * Reserved opcodes in the Java Virtual Machine Specification */ - public static final short IMPDEP2 = 255; - - /** - * BCEL virtual instruction for pushing an arbitrary data type onto the stack. Will be converted to the appropriate JVM - * opcode when the class is dumped. - */ - public static final short PUSH = 4711; - - /** - * BCEL virtual instruction for either LOOKUPSWITCH or TABLESWITCH. Will be converted to the appropriate JVM - * opcode when the class is dumped. - */ - public static final short SWITCH = 4712; - - /** Illegal opcode. */ - public static final short UNDEFINED = -1; - - /** Illegal opcode. */ - public static final short UNPREDICTABLE = -2; - - /** Illegal opcode. */ - public static final short RESERVED = -3; - - /** Mnemonic for an illegal opcode. */ - public static final String ILLEGAL_OPCODE = ""; - - /** Mnemonic for an illegal type. */ - public static final String ILLEGAL_TYPE = ""; - - /** Boolean data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_BOOLEAN = 4; - - /** Char data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_CHAR = 5; - - /** Float data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_FLOAT = 6; - - /** Double data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_DOUBLE = 7; - - /** Byte data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_BYTE = 8; - - /** Short data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_SHORT = 9; - - /** Int data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_INT = 10; - - /** Long data type. - * @see - * Static Constraints in the Java Virtual Machine Specification */ - public static final byte T_LONG = 11; - - /** Void data type (non-standard). */ - public static final byte T_VOID = 12; // Non-standard - - /** Array data type. */ - public static final byte T_ARRAY = 13; - - /** Object data type. */ - public static final byte T_OBJECT = 14; - - /** Reference data type (deprecated). */ - public static final byte T_REFERENCE = 14; // Deprecated - - /** Unknown data type. */ - public static final byte T_UNKNOWN = 15; - - /** Address data type. */ - public static final byte T_ADDRESS = 16; - - /** The primitive type names corresponding to the T_XX constants, - * e.g., TYPE_NAMES[T_INT] = "int" - */ - private static final String[] TYPE_NAMES = { - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, - "boolean", "char", "float", "double", "byte", "short", "int", "long", - "void", "array", "object", "unknown", "address" - }; - - /** - * The primitive type names corresponding to the T_XX constants, - * e.g., TYPE_NAMES[T_INT] = "int" - * @param index - * @return the type name - * @since 6.0 - */ - public static String getTypeName(final int index) { - return TYPE_NAMES[index]; - } - - /** The primitive class names corresponding to the T_XX constants, - * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" - */ - private static final String[] CLASS_TYPE_NAMES = { - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, - "java.lang.Boolean", "java.lang.Character", "java.lang.Float", - "java.lang.Double", "java.lang.Byte", "java.lang.Short", - "java.lang.Integer", "java.lang.Long", "java.lang.Void", - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE - }; - - /** - * The primitive class names corresponding to the T_XX constants, - * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" - * @param index - * @return the class name - * @since 6.0 - */ - public static String getClassTypeName(final int index) { - return CLASS_TYPE_NAMES[index]; - } - - /** The signature characters corresponding to primitive types, - * e.g., SHORT_TYPE_NAMES[T_INT] = "I" - */ - private static final String[] SHORT_TYPE_NAMES = { - ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, - "Z", "C", "F", "D", "B", "S", "I", "J", - "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE - }; - - /** - * - * @param index - * @return the short type name - * @since 6.0 - */ - public static String getShortTypeName(final int index) { - return SHORT_TYPE_NAMES[index]; - } - - - /** - * Number of byte code operands for each opcode, i.e., number of bytes after the tag byte - * itself. Indexed by opcode, so NO_OF_OPERANDS[BIPUSH] = the number of operands for a bipush - * instruction. - */ - private static final short[] NO_OF_OPERANDS = { - 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, - 0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, - 0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/, - 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/, - 1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/, - 1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/, - 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/, - 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, - 0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, - 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/, - 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, - 0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/, - 0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/, - 1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/, - 1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/, - 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/, - 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, - 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, - 0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, - 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/, - 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, - 0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/, - 0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/, - 0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/, - 0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/, - 0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/, - 0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/, - 0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/, - 0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/, - 0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/, - 2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/, - 0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/, - 0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/, - 0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/, - 2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/, - 2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/, - 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/, - 2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/, - 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, - 0/*dreturn*/, 0/*areturn*/, 0/*return*/, - 2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/, - 2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/, - 4/*invokeinterface*/, 4/*invokedynamic*/, 2/*new*/, - 1/*newarray*/, 2/*anewarray*/, - 0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/, - 2/*instanceof*/, 0/*monitorenter*/, - 0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/, - 2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/, - 4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/ - }; - - /** - * - * @param index - * @return Number of byte code operands - * @since 6.0 - */ - public static short getNoOfOperands(final int index) { - return NO_OF_OPERANDS[index]; - } - - /** - * How the byte code operands are to be interpreted for each opcode. - * Indexed by opcode. TYPE_OF_OPERANDS[ILOAD] = an array of shorts - * describing the data types for the instruction. - */ - private static final short[][] TYPE_OF_OPERANDS = { - {}/*nop*/, {}/*aconst_null*/, {}/*iconst_m1*/, {}/*iconst_0*/, - {}/*iconst_1*/, {}/*iconst_2*/, {}/*iconst_3*/, {}/*iconst_4*/, - {}/*iconst_5*/, {}/*lconst_0*/, {}/*lconst_1*/, {}/*fconst_0*/, - {}/*fconst_1*/, {}/*fconst_2*/, {}/*dconst_0*/, {}/*dconst_1*/, - {T_BYTE}/*bipush*/, {T_SHORT}/*sipush*/, {T_BYTE}/*ldc*/, - {T_SHORT}/*ldc_w*/, {T_SHORT}/*ldc2_w*/, - {T_BYTE}/*iload*/, {T_BYTE}/*lload*/, {T_BYTE}/*fload*/, - {T_BYTE}/*dload*/, {T_BYTE}/*aload*/, {}/*iload_0*/, - {}/*iload_1*/, {}/*iload_2*/, {}/*iload_3*/, {}/*lload_0*/, - {}/*lload_1*/, {}/*lload_2*/, {}/*lload_3*/, {}/*fload_0*/, - {}/*fload_1*/, {}/*fload_2*/, {}/*fload_3*/, {}/*dload_0*/, - {}/*dload_1*/, {}/*dload_2*/, {}/*dload_3*/, {}/*aload_0*/, - {}/*aload_1*/, {}/*aload_2*/, {}/*aload_3*/, {}/*iaload*/, - {}/*laload*/, {}/*faload*/, {}/*daload*/, {}/*aaload*/, - {}/*baload*/, {}/*caload*/, {}/*saload*/, {T_BYTE}/*istore*/, - {T_BYTE}/*lstore*/, {T_BYTE}/*fstore*/, {T_BYTE}/*dstore*/, - {T_BYTE}/*astore*/, {}/*istore_0*/, {}/*istore_1*/, - {}/*istore_2*/, {}/*istore_3*/, {}/*lstore_0*/, {}/*lstore_1*/, - {}/*lstore_2*/, {}/*lstore_3*/, {}/*fstore_0*/, {}/*fstore_1*/, - {}/*fstore_2*/, {}/*fstore_3*/, {}/*dstore_0*/, {}/*dstore_1*/, - {}/*dstore_2*/, {}/*dstore_3*/, {}/*astore_0*/, {}/*astore_1*/, - {}/*astore_2*/, {}/*astore_3*/, {}/*iastore*/, {}/*lastore*/, - {}/*fastore*/, {}/*dastore*/, {}/*aastore*/, {}/*bastore*/, - {}/*castore*/, {}/*sastore*/, {}/*pop*/, {}/*pop2*/, {}/*dup*/, - {}/*dup_x1*/, {}/*dup_x2*/, {}/*dup2*/, {}/*dup2_x1*/, - {}/*dup2_x2*/, {}/*swap*/, {}/*iadd*/, {}/*ladd*/, {}/*fadd*/, - {}/*dadd*/, {}/*isub*/, {}/*lsub*/, {}/*fsub*/, {}/*dsub*/, - {}/*imul*/, {}/*lmul*/, {}/*fmul*/, {}/*dmul*/, {}/*idiv*/, - {}/*ldiv*/, {}/*fdiv*/, {}/*ddiv*/, {}/*irem*/, {}/*lrem*/, - {}/*frem*/, {}/*drem*/, {}/*ineg*/, {}/*lneg*/, {}/*fneg*/, - {}/*dneg*/, {}/*ishl*/, {}/*lshl*/, {}/*ishr*/, {}/*lshr*/, - {}/*iushr*/, {}/*lushr*/, {}/*iand*/, {}/*land*/, {}/*ior*/, - {}/*lor*/, {}/*ixor*/, {}/*lxor*/, {T_BYTE, T_BYTE}/*iinc*/, - {}/*i2l*/, {}/*i2f*/, {}/*i2d*/, {}/*l2i*/, {}/*l2f*/, {}/*l2d*/, - {}/*f2i*/, {}/*f2l*/, {}/*f2d*/, {}/*d2i*/, {}/*d2l*/, {}/*d2f*/, - {}/*i2b*/, {}/*i2c*/, {}/*i2s*/, {}/*lcmp*/, {}/*fcmpl*/, - {}/*fcmpg*/, {}/*dcmpl*/, {}/*dcmpg*/, {T_SHORT}/*ifeq*/, - {T_SHORT}/*ifne*/, {T_SHORT}/*iflt*/, {T_SHORT}/*ifge*/, - {T_SHORT}/*ifgt*/, {T_SHORT}/*ifle*/, {T_SHORT}/*if_icmpeq*/, - {T_SHORT}/*if_icmpne*/, {T_SHORT}/*if_icmplt*/, - {T_SHORT}/*if_icmpge*/, {T_SHORT}/*if_icmpgt*/, - {T_SHORT}/*if_icmple*/, {T_SHORT}/*if_acmpeq*/, - {T_SHORT}/*if_acmpne*/, {T_SHORT}/*goto*/, {T_SHORT}/*jsr*/, - {T_BYTE}/*ret*/, {}/*tableswitch*/, {}/*lookupswitch*/, - {}/*ireturn*/, {}/*lreturn*/, {}/*freturn*/, {}/*dreturn*/, - {}/*areturn*/, {}/*return*/, {T_SHORT}/*getstatic*/, - {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/, - {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/, - {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/, - {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {T_SHORT, T_BYTE, T_BYTE}/*invokedynamic*/, - {T_SHORT}/*new*/, {T_BYTE}/*newarray*/, - {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/, - {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/, - {}/*monitorenter*/, {}/*monitorexit*/, {T_BYTE}/*wide*/, - {T_SHORT, T_BYTE}/*multianewarray*/, {T_SHORT}/*ifnull*/, - {T_SHORT}/*ifnonnull*/, {T_INT}/*goto_w*/, {T_INT}/*jsr_w*/, - {}/*breakpoint*/, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, - {}/*impdep1*/, {}/*impdep2*/ - }; - - /** - * @since 6.0 - */ - public static short getOperandType(final int opcode, final int index) { - return TYPE_OF_OPERANDS[opcode][index]; - } - - /** - * @since 6.0 - */ - public static long getOperandTypeCount(final int opcode) { - return TYPE_OF_OPERANDS[opcode].length; - } - - /** - * Names of opcodes. Indexed by opcode. OPCODE_NAMES[ALOAD] = "aload". - */ - private static final String[] OPCODE_NAMES = { - "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1", - "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0", - "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0", - "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", - "lload", "fload", "dload", "aload", "iload_0", "iload_1", "iload_2", - "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", - "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2", - "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload", - "laload", "faload", "daload", "aaload", "baload", "caload", "saload", - "istore", "lstore", "fstore", "dstore", "astore", "istore_0", - "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", - "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2", - "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", - "astore_0", "astore_1", "astore_2", "astore_3", "iastore", "lastore", - "fastore", "dastore", "aastore", "bastore", "castore", "sastore", - "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1", - "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub", - "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv", - "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg", - "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", - "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f", - "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", - "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", - "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", - "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", - "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", - "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn", - "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield", - "putfield", "invokevirtual", "invokespecial", "invokestatic", - "invokeinterface", "invokedynamic", "new", "newarray", "anewarray", - "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", - "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull", - "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, - ILLEGAL_OPCODE, "impdep1", "impdep2" - }; - - /** - * @since 6.0 - */ - public static final int OPCODE_NAMES_LENGTH = OPCODE_NAMES.length; - - - /** - * @since 6.0 - */ - public static String getOpcodeName(final int index) { - return OPCODE_NAMES[index]; - } - - /** - * Number of words consumed on operand stack by instructions. - * Indexed by opcode. CONSUME_STACK[FALOAD] = number of words - * consumed from the stack by a faload instruction. - */ - private static final int[] CONSUME_STACK = { - 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, 0/*iconst_1*/, - 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, 0/*iconst_5*/, 0/*lconst_0*/, - 0/*lconst_1*/, 0/*fconst_0*/, 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, - 0/*dconst_1*/, 0/*bipush*/, 0/*sipush*/, 0/*ldc*/, 0/*ldc_w*/, 0/*ldc2_w*/, 0/*iload*/, - 0/*lload*/, 0/*fload*/, 0/*dload*/, 0/*aload*/, 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, - 0/*iload_3*/, 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, 0/*fload_0*/, - 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, - 0/*dload_3*/, 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, 2/*iaload*/, - 2/*laload*/, 2/*faload*/, 2/*daload*/, 2/*aaload*/, 2/*baload*/, 2/*caload*/, 2/*saload*/, - 1/*istore*/, 2/*lstore*/, 1/*fstore*/, 2/*dstore*/, 1/*astore*/, 1/*istore_0*/, - 1/*istore_1*/, 1/*istore_2*/, 1/*istore_3*/, 2/*lstore_0*/, 2/*lstore_1*/, - 2/*lstore_2*/, 2/*lstore_3*/, 1/*fstore_0*/, 1/*fstore_1*/, 1/*fstore_2*/, - 1/*fstore_3*/, 2/*dstore_0*/, 2/*dstore_1*/, 2/*dstore_2*/, 2/*dstore_3*/, - 1/*astore_0*/, 1/*astore_1*/, 1/*astore_2*/, 1/*astore_3*/, 3/*iastore*/, 4/*lastore*/, - 3/*fastore*/, 4/*dastore*/, 3/*aastore*/, 3/*bastore*/, 3/*castore*/, 3/*sastore*/, - 1/*pop*/, 2/*pop2*/, 1/*dup*/, 2/*dup_x1*/, 3/*dup_x2*/, 2/*dup2*/, 3/*dup2_x1*/, - 4/*dup2_x2*/, 2/*swap*/, 2/*iadd*/, 4/*ladd*/, 2/*fadd*/, 4/*dadd*/, 2/*isub*/, 4/*lsub*/, - 2/*fsub*/, 4/*dsub*/, 2/*imul*/, 4/*lmul*/, 2/*fmul*/, 4/*dmul*/, 2/*idiv*/, 4/*ldiv*/, - 2/*fdiv*/, 4/*ddiv*/, 2/*irem*/, 4/*lrem*/, 2/*frem*/, 4/*drem*/, 1/*ineg*/, 2/*lneg*/, - 1/*fneg*/, 2/*dneg*/, 2/*ishl*/, 3/*lshl*/, 2/*ishr*/, 3/*lshr*/, 2/*iushr*/, 3/*lushr*/, - 2/*iand*/, 4/*land*/, 2/*ior*/, 4/*lor*/, 2/*ixor*/, 4/*lxor*/, 0/*iinc*/, - 1/*i2l*/, 1/*i2f*/, 1/*i2d*/, 2/*l2i*/, 2/*l2f*/, 2/*l2d*/, 1/*f2i*/, 1/*f2l*/, - 1/*f2d*/, 2/*d2i*/, 2/*d2l*/, 2/*d2f*/, 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, - 4/*lcmp*/, 2/*fcmpl*/, 2/*fcmpg*/, 4/*dcmpl*/, 4/*dcmpg*/, 1/*ifeq*/, 1/*ifne*/, - 1/*iflt*/, 1/*ifge*/, 1/*ifgt*/, 1/*ifle*/, 2/*if_icmpeq*/, 2/*if_icmpne*/, 2/*if_icmplt*/, - 2 /*if_icmpge*/, 2/*if_icmpgt*/, 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, - 0/*goto*/, 0/*jsr*/, 0/*ret*/, 1/*tableswitch*/, 1/*lookupswitch*/, 1/*ireturn*/, - 2/*lreturn*/, 1/*freturn*/, 2/*dreturn*/, 1/*areturn*/, 0/*return*/, 0/*getstatic*/, - UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/, - UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/, - UNPREDICTABLE/*invokestatic*/, - UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 0/*new*/, 1/*newarray*/, 1/*anewarray*/, - 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/, - 1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/, - 0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ - }; - - /** - * - * @param index - * @return Number of words consumed on operand stack - * @since 6.0 - */ - public static int getConsumeStack(final int index) { - return CONSUME_STACK[index]; - } - - - /** - * Number of words produced onto operand stack by instructions. - * Indexed by opcode. CONSUME_STACK[DALOAD] = number of words - * consumed from the stack by a daload instruction. - */ - private static final int[] PRODUCE_STACK = { - 0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/, - 1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/, - 2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/, - 2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/, - 2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/, - 1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/, - 1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/, - 2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/, - 2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/, - 0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/, - 0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, - 0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, - 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/, - 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, - 0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/, - 0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/, - 6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/, - 1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/, - 1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/, - 1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/, - 1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/, - 0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/, - 2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/, - 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/, - 1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/, - 0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/, - 0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/, - 0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, - 0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/, - UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/, - UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/, - UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 1/*new*/, 1/*newarray*/, 1/*anewarray*/, - 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/, - 0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/, - 0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, - UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ - }; - - /** - * - * @param index - * @return Number of words produced onto operand stack - * @since 6.0 - */ - public static int getProduceStack(final int index) { - return PRODUCE_STACK[index]; - } - - /** Attributes and their corresponding names. - */ - public static final byte ATTR_UNKNOWN = -1; - public static final byte ATTR_SOURCE_FILE = 0; - public static final byte ATTR_CONSTANT_VALUE = 1; - public static final byte ATTR_CODE = 2; - public static final byte ATTR_EXCEPTIONS = 3; - public static final byte ATTR_LINE_NUMBER_TABLE = 4; - public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; - public static final byte ATTR_INNER_CLASSES = 6; - public static final byte ATTR_SYNTHETIC = 7; - public static final byte ATTR_DEPRECATED = 8; - public static final byte ATTR_PMG = 9; - public static final byte ATTR_SIGNATURE = 10; - public static final byte ATTR_STACK_MAP = 11; - public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS = 12; - public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS = 13; - public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = 14; - public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15; - public static final byte ATTR_ANNOTATION_DEFAULT = 16; - public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 17; - public static final byte ATTR_ENCLOSING_METHOD = 18; - public static final byte ATTR_STACK_MAP_TABLE = 19; - public static final byte ATTR_BOOTSTRAP_METHODS = 20; - public static final byte ATTR_METHOD_PARAMETERS = 21; - public static final byte ATTR_MODULE = 22; - public static final byte ATTR_MODULE_PACKAGES = 23; - public static final byte ATTR_MODULE_MAIN_CLASS = 24; - public static final byte ATTR_NEST_HOST = 25; - public static final byte ATTR_NEST_MEMBERS = 26; - - public static final short KNOWN_ATTRIBUTES = 27; // count of attributes - - private static final String[] ATTRIBUTE_NAMES = { - "SourceFile", "ConstantValue", "Code", "Exceptions", - "LineNumberTable", "LocalVariableTable", - "InnerClasses", "Synthetic", "Deprecated", - "PMGClass", "Signature", "StackMap", - "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", - "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", - "AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", "StackMapTable", - "BootstrapMethods", "MethodParameters", "Module", "ModulePackages", - "ModuleMainClass", "NestHost", "NestMembers" - }; - - /** - * - * @param index - * @return the attribute name - * @since 6.0 - */ - public static String getAttributeName(final int index) { - return ATTRIBUTE_NAMES[index]; - } - - /** Constants used in the StackMap attribute. - */ - public static final byte ITEM_Bogus = 0; - public static final byte ITEM_Integer = 1; - public static final byte ITEM_Float = 2; - public static final byte ITEM_Double = 3; - public static final byte ITEM_Long = 4; - public static final byte ITEM_Null = 5; - public static final byte ITEM_InitObject = 6; - public static final byte ITEM_Object = 7; - public static final byte ITEM_NewObject = 8; - - private static final String[] ITEM_NAMES = { - "Bogus", "Integer", "Float", "Double", "Long", - "Null", "InitObject", "Object", "NewObject" - }; - - /** - * - * @param index - * @return the item name - * @since 6.0 - */ - public static String getItemName(final int index) { - return ITEM_NAMES[index]; - } - - /** Constants used to identify StackMapEntry types. - * - * For those types which can specify a range, the - * constant names the lowest value. - */ - public static final int SAME_FRAME = 0; - public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; - public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; - public static final int CHOP_FRAME = 248; - public static final int SAME_FRAME_EXTENDED = 251; - public static final int APPEND_FRAME = 252; - public static final int FULL_FRAME = 255; - - /** Constants that define the maximum value of - * those constants which store ranges. */ - - public static final int SAME_FRAME_MAX = 63; - public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_MAX = 127; - public static final int CHOP_FRAME_MAX = 250; - public static final int APPEND_FRAME_MAX = 254; - - - // Constants defining the behavior of the Method Handles (JVMS 5.4.3.5) - - public static final byte REF_getField = 1; - public static final byte REF_getStatic = 2; - public static final byte REF_putField = 3; - public static final byte REF_putStatic = 4; - public static final byte REF_invokeVirtual = 5; - public static final byte REF_invokeStatic = 6; - public static final byte REF_invokeSpecial = 7; - public static final byte REF_newInvokeSpecial = 8; - public static final byte REF_invokeInterface = 9; - - /** - * The names of the reference_kinds of a CONSTANT_MethodHandle_info. - */ - private static final String[] METHODHANDLE_NAMES = { - "", "getField", "getStatic", "putField", "putStatic", "invokeVirtual", - "invokeStatic", "invokeSpecial", "newInvokeSpecial", "invokeInterface" }; - - /** - * - * @param index - * @return the method handle name - * @since 6.0 - */ - public static String getMethodHandleName(final int index) { - return METHODHANDLE_NAMES[index]; - } + /** + * Java class file format Magic number (0xCAFEBABE) + * + * @see The ClassFile Structure + * in The Java Virtual Machine Specification + */ + public static final int JVM_CLASSFILE_MAGIC = 0xCAFEBABE; + + /** + * Major version number of class files for Java 1.1. + * + * @see #MINOR_1_1 + */ + public static final short MAJOR_1_1 = 45; + + /** + * Minor version number of class files for Java 1.1. + * + * @see #MAJOR_1_1 + */ + public static final short MINOR_1_1 = 3; + + /** + * Major version number of class files for Java 1.2. + * + * @see #MINOR_1_2 + */ + public static final short MAJOR_1_2 = 46; + + /** + * Minor version number of class files for Java 1.2. + * + * @see #MAJOR_1_2 + */ + public static final short MINOR_1_2 = 0; + + /** + * Major version number of class files for Java 1.2. + * + * @see #MINOR_1_2 + */ + public static final short MAJOR_1_3 = 47; + + /** + * Minor version number of class files for Java 1.3. + * + * @see #MAJOR_1_3 + */ + public static final short MINOR_1_3 = 0; + + /** + * Major version number of class files for Java 1.3. + * + * @see #MINOR_1_3 + */ + public static final short MAJOR_1_4 = 48; + + /** + * Minor version number of class files for Java 1.4. + * + * @see #MAJOR_1_4 + */ + public static final short MINOR_1_4 = 0; + + /** + * Major version number of class files for Java 1.4. + * + * @see #MINOR_1_4 + */ + public static final short MAJOR_1_5 = 49; + + /** + * Minor version number of class files for Java 1.5. + * + * @see #MAJOR_1_5 + */ + public static final short MINOR_1_5 = 0; + + /** + * Major version number of class files for Java 1.6. + * + * @see #MINOR_1_6 + */ + public static final short MAJOR_1_6 = 50; + + /** + * Minor version number of class files for Java 1.6. + * + * @see #MAJOR_1_6 + */ + public static final short MINOR_1_6 = 0; + + /** + * Major version number of class files for Java 1.7. + * + * @see #MINOR_1_7 + */ + public static final short MAJOR_1_7 = 51; + + /** + * Minor version number of class files for Java 1.7. + * + * @see #MAJOR_1_7 + */ + public static final short MINOR_1_7 = 0; + + /** + * Major version number of class files for Java 1.8. + * + * @see #MINOR_1_8 + */ + public static final short MAJOR_1_8 = 52; + + /** + * Minor version number of class files for Java 1.8. + * + * @see #MAJOR_1_8 + */ + public static final short MINOR_1_8 = 0; + + /** + * Major version number of class files for Java 9. + * + * @see #MINOR_9 + */ + public static final short MAJOR_9 = 53; + + /** + * Minor version number of class files for Java 9. + * + * @see #MAJOR_9 + */ + public static final short MINOR_9 = 0; + + /** + * @deprecated Use {@link #MAJOR_9} instead + */ + @Deprecated + public static final short MAJOR_1_9 = MAJOR_9; + + /** + * @deprecated Use {@link #MINOR_9} instead + */ + @Deprecated + public static final short MINOR_1_9 = MINOR_9; + + /** + * Major version number of class files for Java 10. + * + * @see #MINOR_10 + */ + public static final short MAJOR_10 = 54; + + /** + * Minor version number of class files for Java 10. + * + * @see #MAJOR_10 + */ + public static final short MINOR_10 = 0; + + /** + * Major version number of class files for Java 11. + * + * @see #MINOR_11 + */ + public static final short MAJOR_11 = 55; + + /** + * Minor version number of class files for Java 11. + * + * @see #MAJOR_11 + */ + public static final short MINOR_11 = 0; + + /** + * Major version number of class files for Java 12. + * + * @see #MINOR_12 + */ + public static final short MAJOR_12 = 56; + + /** + * Minor version number of class files for Java 12. + * + * @see #MAJOR_12 + */ + public static final short MINOR_12 = 0; + + /** + * Major version number of class files for Java 13. + * + * @see #MINOR_13 + */ + public static final short MAJOR_13 = 57; + + /** + * Minor version number of class files for Java 13. + * + * @see #MAJOR_13 + */ + public static final short MINOR_13 = 0; + + /** + * Minor version number of class files for Java 14. + * + * @see #MAJOR_14 + * @since 6.4.0 + */ + public static final short MINOR_14 = 0; + + /** + * Minor version number of class files for Java 15. + * + * @see #MAJOR_15 + * @since 6.6.0 + */ + public static final short MINOR_15 = 0; + + /** + * Minor version number of class files for Java 16. + * + * @see #MAJOR_16 + * @since 6.6.0 + */ + public static final short MINOR_16 = 0; + + /** + * Minor version number of class files for Java 17. + * + * @see #MAJOR_17 + * @since 6.6.0 + */ + public static final short MINOR_17 = 0; + + /** + * Minor version number of class files for Java 18. + * + * @see #MAJOR_18 + * @since 6.6.0 + */ + public static final short MINOR_18 = 0; + + /** + * Minor version number of class files for Java 19. + * + * @see #MAJOR_19 + * @since 6.6.0 + */ + public static final short MINOR_19 = 0; + + /** + * Major version number of class files for Java 14. + * + * @see #MINOR_14 + * @since 6.4.0 + */ + public static final short MAJOR_14 = 58; + + /** + * Major version number of class files for Java 15. + * + * @see #MINOR_15 + * @since 6.6.0 + */ + public static final short MAJOR_15 = 59; + + /** + * Major version number of class files for Java 16. + * + * @see #MINOR_16 + * @since 6.6.0 + */ + public static final short MAJOR_16 = 60; + + /** + * Major version number of class files for Java 17. + * + * @see #MINOR_17 + * @since 6.6.0 + */ + public static final short MAJOR_17 = 61; + + /** + * Major version number of class files for Java 18. + * + * @see #MINOR_18 + * @since 6.6.0 + */ + public static final short MAJOR_18 = 62; + + /** + * Major version number of class files for Java 19. + * + * @see #MINOR_19 + * @since 6.6.0 + */ + public static final short MAJOR_19 = 63; + + /** + * Default major version number. Class file is for Java 1.1. + * + * @see #MAJOR_1_1 + */ + public static final short MAJOR = MAJOR_1_1; + + /** + * Default major version number. Class file is for Java 1.1. + * + * @see #MAJOR_1_1 + */ + public static final short MINOR = MINOR_1_1; + + /** + * Maximum value for an unsigned short. + */ + public static final int MAX_SHORT = 65535; // 2^16 - 1 + + /** + * Maximum value for an unsigned byte. + */ + public static final int MAX_BYTE = 255; // 2^8 - 1 + + /** + * One of the access flags for fields, methods, or classes. + * + * @see Flag definitions for + * Classes in the Java Virtual Machine Specification (Java SE 9 Edition). + * @see Flag definitions for Fields + * in the Java Virtual Machine Specification (Java SE 9 Edition). + * @see Flag definitions for Methods + * in the Java Virtual Machine Specification (Java SE 9 Edition). + * @see Flag + * definitions for Inner Classes in the Java Virtual Machine Specification (Java SE 9 Edition). + */ + public static final short ACC_PUBLIC = 0x0001; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_PRIVATE = 0x0002; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_PROTECTED = 0x0004; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_STATIC = 0x0008; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_FINAL = 0x0010; + + /** + * One of the access flags for the Module attribute. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_OPEN = 0x0020; + + /** + * One of the access flags for classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_SUPER = 0x0020; + + /** + * One of the access flags for methods. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_SYNCHRONIZED = 0x0020; + + /** + * One of the access flags for the Module attribute. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_TRANSITIVE = 0x0020; + + /** + * One of the access flags for methods. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_BRIDGE = 0x0040; + + /** + * One of the access flags for the Module attribute. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_STATIC_PHASE = 0x0040; + + /** + * One of the access flags for fields. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_VOLATILE = 0x0040; + + /** + * One of the access flags for fields. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_TRANSIENT = 0x0080; + + /** + * One of the access flags for methods. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_VARARGS = 0x0080; + + /** + * One of the access flags for methods. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_NATIVE = 0x0100; + + /** + * One of the access flags for classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_INTERFACE = 0x0200; + + /** + * One of the access flags for methods or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_ABSTRACT = 0x0400; + + /** + * One of the access flags for methods. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_STRICT = 0x0800; + + /** + * One of the access flags for fields, methods, classes, MethodParameter attribute, or Module attribute. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_SYNTHETIC = 0x1000; + + /** + * One of the access flags for classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_ANNOTATION = 0x2000; + + /** + * One of the access flags for fields or classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_ENUM = 0x4000; + + // Applies to classes compiled by new compilers only + /** + * One of the access flags for MethodParameter or Module attributes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_MANDATED = (short) 0x8000; + + /** + * One of the access flags for classes. + * + * @see #ACC_PUBLIC + */ + public static final short ACC_MODULE = (short) 0x8000; + + /** + * One of the access flags for fields, methods, or classes. + * + * @see #ACC_PUBLIC + * @deprecated Use {@link #MAX_ACC_FLAG_I} + */ + @Deprecated + public static final short MAX_ACC_FLAG = ACC_ENUM; + + /** + * One of the access flags for fields, methods, or classes. ACC_MODULE is negative as a short. + * + * @see #ACC_PUBLIC + * @since 6.4.0 + */ + public static final int MAX_ACC_FLAG_I = 0x8000; // ACC_MODULE is negative as a short + + // Note that do to overloading: + // 'synchronized' is for methods, might be 'open' (if Module), 'super' (if class), or 'transitive' (if Module). + // 'volatile' is for fields, might be 'bridge' (if method) or 'static_phase' (if Module) + // 'transient' is for fields, might be 'varargs' (if method) + // 'module' is for classes, might be 'mandated' (if Module or MethodParameters) + /** + * The names of the access flags. + */ + private static final String[] ACCESS_NAMES = {"public", "private", "protected", "static", "final", "synchronized", "volatile", "transient", "native", + "interface", "abstract", "strictfp", "synthetic", "annotation", "enum", "module"}; + + /** @since 6.0 */ + public static final int ACCESS_NAMES_LENGTH = ACCESS_NAMES.length; + + /** + * Marks a constant pool entry as type UTF-8. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Utf8 = 1; + + /* + * The description of the constant pool is at: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4 + * References below are to the individual sections + */ + + /** + * Marks a constant pool entry as type Integer. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Integer = 3; + + /** + * Marks a constant pool entry as type Float. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Float = 4; + + /** + * Marks a constant pool entry as type Long. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Long = 5; + + /** + * Marks a constant pool entry as type Double. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Double = 6; + + /** + * Marks a constant pool entry as a Class + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Class = 7; + + /** + * Marks a constant pool entry as a Field Reference. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Fieldref = 9; + + /** + * Marks a constant pool entry as type String + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_String = 8; + + /** + * Marks a constant pool entry as a Method Reference. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_Methodref = 10; + + /** + * Marks a constant pool entry as an Interface Method Reference. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_InterfaceMethodref = 11; + + /** + * Marks a constant pool entry as a name and type. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_NameAndType = 12; + + /** + * Marks a constant pool entry as a Method Handle. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_MethodHandle = 15; + + /** + * Marks a constant pool entry as a Method Type. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_MethodType = 16; + + /** + * Marks a constant pool entry as dynamically computed. + * + * @see Change request for JEP + * 309 + * @since 6.3 + */ + public static final byte CONSTANT_Dynamic = 17; + + /** + * Marks a constant pool entry as an Invoke Dynamic + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + */ + public static final byte CONSTANT_InvokeDynamic = 18; + + /** + * Marks a constant pool entry as a Module Reference. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + * @since 6.1 + */ + public static final byte CONSTANT_Module = 19; + + /** + * Marks a constant pool entry as a Package Reference. + * + * @see The Constant Pool in The + * Java Virtual Machine Specification + * @since 6.1 + */ + public static final byte CONSTANT_Package = 20; + + /** + * The names of the types of entries in a constant pool. Use getConstantName instead + */ + private static final String[] CONSTANT_NAMES = {"", "CONSTANT_Utf8", "", "CONSTANT_Integer", "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", + "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref", "CONSTANT_NameAndType", "", "", + "CONSTANT_MethodHandle", "CONSTANT_MethodType", "CONSTANT_Dynamic", "CONSTANT_InvokeDynamic", "CONSTANT_Module", "CONSTANT_Package"}; + + /** + * The name of the static initializer, also called "class initialization method" or "interface + * initialization method". This is "<clinit>". + */ + public static final String STATIC_INITIALIZER_NAME = ""; + + /** + * The name of every constructor method in a class, also called "instance initialization method". This is + * "<init>". + */ + public static final String CONSTRUCTOR_NAME = ""; + + /** + * The names of the interfaces implemented by arrays + */ + private static final String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"}; + + /** + * Maximum Constant Pool entries. One of the limitations of the Java Virtual Machine. + * + * @see The Java Virtual + * Machine Specification, Java SE 8 Edition, page 330, chapter 4.11. + */ + public static final int MAX_CP_ENTRIES = 65535; + + /** + * Maximum code size (plus one; the code size must be LESS than this) One of the limitations of the Java Virtual + * Machine. Note vmspec2 page 152 ("Limitations") says: "The amount of code per non-native, non-abstract method is + * limited to 65536 bytes by the sizes of the indices in the exception_table of the Code attribute (4.7.3), in the + * LineNumberTable attribute (4.7.8), and in the LocalVariableTable attribute (4.7.9)." However this should be taken + * as an upper limit rather than the defined maximum. On page 134 (4.8.1 Static Constants) of the same spec, it says: + * "The value of the code_length item must be less than 65536." The entry in the Limitations section has been removed + * from later versions of the spec; it is not present in the Java SE 8 edition. + * + * @see The Java Virtual + * Machine Specification, Java SE 8 Edition, page 104, chapter 4.7. + */ + public static final int MAX_CODE_SIZE = 65536; // bytes + + /** + * The maximum number of dimensions in an array ({@value}). One of the limitations of the Java Virtual Machine. + * + * @see Field Descriptors in + * The Java Virtual Machine Specification + */ + public static final int MAX_ARRAY_DIMENSIONS = 255; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short NOP = 0; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short ACONST_NULL = 1; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_M1 = 2; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_0 = 3; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_1 = 4; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_2 = 5; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_3 = 6; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_4 = 7; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ICONST_5 = 8; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short LCONST_0 = 9; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short LCONST_1 = 10; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FCONST_0 = 11; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FCONST_1 = 12; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FCONST_2 = 13; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short DCONST_0 = 14; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short DCONST_1 = 15; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short BIPUSH = 16; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short SIPUSH = 17; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short LDC = 18; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LDC_W = 19; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LDC2_W = 20; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ILOAD = 21; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LLOAD = 22; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FLOAD = 23; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DLOAD = 24; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ALOAD = 25; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ILOAD_0 = 26; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ILOAD_1 = 27; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ILOAD_2 = 28; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ILOAD_3 = 29; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LLOAD_0 = 30; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LLOAD_1 = 31; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LLOAD_2 = 32; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LLOAD_3 = 33; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FLOAD_0 = 34; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FLOAD_1 = 35; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FLOAD_2 = 36; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FLOAD_3 = 37; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DLOAD_0 = 38; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DLOAD_1 = 39; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DLOAD_2 = 40; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DLOAD_3 = 41; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ALOAD_0 = 42; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ALOAD_1 = 43; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ALOAD_2 = 44; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ALOAD_3 = 45; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IALOAD = 46; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LALOAD = 47; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FALOAD = 48; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DALOAD = 49; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short AALOAD = 50; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short BALOAD = 51; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short CALOAD = 52; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short SALOAD = 53; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ISTORE = 54; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LSTORE = 55; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FSTORE = 56; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DSTORE = 57; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ASTORE = 58; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ISTORE_0 = 59; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ISTORE_1 = 60; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ISTORE_2 = 61; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ISTORE_3 = 62; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short LSTORE_0 = 63; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short LSTORE_1 = 64; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short LSTORE_2 = 65; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short LSTORE_3 = 66; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FSTORE_0 = 67; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FSTORE_1 = 68; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FSTORE_2 = 69; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short FSTORE_3 = 70; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short DSTORE_0 = 71; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short DSTORE_1 = 72; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short DSTORE_2 = 73; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short DSTORE_3 = 74; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ASTORE_0 = 75; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ASTORE_1 = 76; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ASTORE_2 = 77; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ASTORE_3 = 78; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IASTORE = 79; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LASTORE = 80; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FASTORE = 81; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DASTORE = 82; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short AASTORE = 83; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short BASTORE = 84; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short CASTORE = 85; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short SASTORE = 86; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short POP = 87; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short POP2 = 88; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short DUP = 89; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DUP_X1 = 90; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DUP_X2 = 91; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DUP2 = 92; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DUP2_X1 = 93; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DUP2_X2 = 94; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short SWAP = 95; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IADD = 96; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LADD = 97; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FADD = 98; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DADD = 99; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ISUB = 100; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LSUB = 101; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FSUB = 102; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DSUB = 103; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IMUL = 104; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LMUL = 105; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FMUL = 106; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DMUL = 107; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IDIV = 108; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LDIV = 109; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FDIV = 110; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DDIV = 111; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IREM = 112; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LREM = 113; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FREM = 114; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DREM = 115; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short INEG = 116; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LNEG = 117; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FNEG = 118; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DNEG = 119; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ISHL = 120; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LSHL = 121; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ISHR = 122; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LSHR = 123; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IUSHR = 124; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LUSHR = 125; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IAND = 126; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LAND = 127; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short IOR = 128; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short LOR = 129; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IXOR = 130; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LXOR = 131; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IINC = 132; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short I2L = 133; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short I2F = 134; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short I2D = 135; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short L2I = 136; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short L2F = 137; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short L2D = 138; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short F2I = 139; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short F2L = 140; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short F2D = 141; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short D2I = 142; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short D2L = 143; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short D2F = 144; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short I2B = 145; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short INT2BYTE = 145; // Old notation + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short I2C = 146; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short INT2CHAR = 146; // Old notation + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short I2S = 147; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short INT2SHORT = 147; // Old notation + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LCMP = 148; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FCMPL = 149; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FCMPG = 150; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DCMPL = 151; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DCMPG = 152; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFEQ = 153; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFNE = 154; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFLT = 155; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFGE = 156; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFGT = 157; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFLE = 158; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPEQ = 159; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPNE = 160; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPLT = 161; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPGE = 162; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPGT = 163; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ICMPLE = 164; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ACMPEQ = 165; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short IF_ACMPNE = 166; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short GOTO = 167; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short JSR = 168; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short RET = 169; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short TABLESWITCH = 170; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short LOOKUPSWITCH = 171; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IRETURN = 172; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short LRETURN = 173; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short FRETURN = 174; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short DRETURN = 175; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ARETURN = 176; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short RETURN = 177; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short GETSTATIC = 178; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short PUTSTATIC = 179; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short GETFIELD = 180; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short PUTFIELD = 181; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short INVOKEVIRTUAL = 182; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short INVOKESPECIAL = 183; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short INVOKESTATIC = 184; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short INVOKEINTERFACE = 185; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short INVOKEDYNAMIC = 186; + + /** + * Java VM opcode. + * + * @see Opcode definitions in The + * Java Virtual Machine Specification + */ + public static final short NEW = 187; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short NEWARRAY = 188; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short ANEWARRAY = 189; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short ARRAYLENGTH = 190; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short ATHROW = 191; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short CHECKCAST = 192; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short INSTANCEOF = 193; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short MONITORENTER = 194; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short MONITOREXIT = 195; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short WIDE = 196; + + /** + * Java VM opcode. + * + * @see Opcode + * definitions in The Java Virtual Machine Specification + */ + public static final short MULTIANEWARRAY = 197; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short IFNULL = 198; + + /** + * Java VM opcode. + * + * @see Opcode definitions + * in The Java Virtual Machine Specification + */ + public static final short IFNONNULL = 199; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short GOTO_W = 200; + + /** + * Java VM opcode. + * + * @see Opcode definitions in + * The Java Virtual Machine Specification + */ + public static final short JSR_W = 201; + + /** + * JVM internal opcode. + * + * @see Reserved opcodes in the Java + * Virtual Machine Specification + */ + public static final short BREAKPOINT = 202; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short LDC_QUICK = 203; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short LDC_W_QUICK = 204; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short LDC2_W_QUICK = 205; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short GETFIELD_QUICK = 206; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short PUTFIELD_QUICK = 207; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short GETFIELD2_QUICK = 208; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short PUTFIELD2_QUICK = 209; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short GETSTATIC_QUICK = 210; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short PUTSTATIC_QUICK = 211; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short GETSTATIC2_QUICK = 212; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short PUTSTATIC2_QUICK = 213; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKEVIRTUAL_QUICK = 214; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKENONVIRTUAL_QUICK = 215; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKESUPER_QUICK = 216; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKESTATIC_QUICK = 217; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKEINTERFACE_QUICK = 218; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKEVIRTUALOBJECT_QUICK = 219; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short NEW_QUICK = 221; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short ANEWARRAY_QUICK = 222; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short MULTIANEWARRAY_QUICK = 223; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short CHECKCAST_QUICK = 224; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INSTANCEOF_QUICK = 225; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short INVOKEVIRTUAL_QUICK_W = 226; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short GETFIELD_QUICK_W = 227; + + /** + * JVM internal opcode. + * + * @see + * Specification of _quick opcodes in the Java Virtual Machine Specification (version 1) + * @see Why the _quick + * opcodes were removed from the second version of the Java Virtual Machine Specification. + */ + public static final short PUTFIELD_QUICK_W = 228; + + /** + * JVM internal opcode. + * + * @see Reserved opcodes in the Java + * Virtual Machine Specification + */ + public static final short IMPDEP1 = 254; + + /** + * JVM internal opcode. + * + * @see Reserved opcodes in the Java + * Virtual Machine Specification + */ + public static final short IMPDEP2 = 255; + + /** + * BCEL virtual instruction for pushing an arbitrary data type onto the stack. Will be converted to the appropriate JVM + * opcode when the class is dumped. + */ + public static final short PUSH = 4711; + + /** + * BCEL virtual instruction for either LOOKUPSWITCH or TABLESWITCH. Will be converted to the appropriate JVM opcode when + * the class is dumped. + */ + public static final short SWITCH = 4712; + + /** Illegal opcode. */ + public static final short UNDEFINED = -1; + + /** Illegal opcode. */ + public static final short UNPREDICTABLE = -2; + + /** Illegal opcode. */ + public static final short RESERVED = -3; + + /** Mnemonic for an illegal opcode. */ + public static final String ILLEGAL_OPCODE = ""; + + /** Mnemonic for an illegal type. */ + public static final String ILLEGAL_TYPE = ""; + + /** + * Boolean data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_BOOLEAN = 4; + + /** + * Char data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_CHAR = 5; + + /** + * Float data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_FLOAT = 6; + + /** + * Double data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_DOUBLE = 7; + + /** + * Byte data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_BYTE = 8; + + /** + * Short data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_SHORT = 9; + + /** + * Int data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_INT = 10; + + /** + * Long data type. + * + * @see Static Constraints in + * the Java Virtual Machine Specification + */ + public static final byte T_LONG = 11; + + /** Void data type (non-standard). */ + public static final byte T_VOID = 12; // Non-standard + + /** Array data type. */ + public static final byte T_ARRAY = 13; + + /** Object data type. */ + public static final byte T_OBJECT = 14; + + /** Reference data type (deprecated). */ + public static final byte T_REFERENCE = 14; // Deprecated + + /** Unknown data type. */ + public static final byte T_UNKNOWN = 15; + + /** Address data type. */ + public static final byte T_ADDRESS = 16; + + /** Empty arrays used to replace references to ArrayUtils */ + public static final byte[] EMPTY_BYTE_ARRAY = {}; + public static final int[] EMPTY_INT_ARRAY = {}; + public static final String[] EMPTY_STRING_ARRAY = {}; + + /** + * The primitive type names corresponding to the T_XX constants, e.g., TYPE_NAMES[T_INT] = "int" + */ + private static final String[] TYPE_NAMES = {ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "boolean", "char", "float", "double", "byte", "short", + "int", "long", "void", "array", "object", "unknown", "address"}; + + /** + * The primitive class names corresponding to the T_XX constants, e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + */ + private static final String[] CLASS_TYPE_NAMES = {ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "java.lang.Boolean", "java.lang.Character", + "java.lang.Float", "java.lang.Double", "java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Long", "java.lang.Void", ILLEGAL_TYPE, + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE}; + + /** + * The signature characters corresponding to primitive types, e.g., SHORT_TYPE_NAMES[T_INT] = "I" + */ + private static final String[] SHORT_TYPE_NAMES = {ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, "Z", "C", "F", "D", "B", "S", "I", "J", "V", + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE}; + + /** + * Number of byte code operands for each opcode, i.e., number of bytes after the tag byte itself. Indexed by opcode, so + * NO_OF_OPERANDS[BIPUSH] = the number of operands for a bipush instruction. + */ + static final short[] NO_OF_OPERANDS = {0/* nop */, 0/* aconst_null */, 0/* iconst_m1 */, 0/* iconst_0 */, 0/* iconst_1 */, 0/* iconst_2 */, + 0/* iconst_3 */, 0/* iconst_4 */, 0/* iconst_5 */, 0/* lconst_0 */, 0/* lconst_1 */, 0/* fconst_0 */, 0/* fconst_1 */, 0/* fconst_2 */, 0/* dconst_0 */, + 0/* dconst_1 */, 1/* bipush */, 2/* sipush */, 1/* ldc */, 2/* ldc_w */, 2/* ldc2_w */, 1/* iload */, 1/* lload */, 1/* fload */, 1/* dload */, + 1/* aload */, 0/* iload_0 */, 0/* iload_1 */, 0/* iload_2 */, 0/* iload_3 */, 0/* lload_0 */, 0/* lload_1 */, 0/* lload_2 */, 0/* lload_3 */, + 0/* fload_0 */, 0/* fload_1 */, 0/* fload_2 */, 0/* fload_3 */, 0/* dload_0 */, 0/* dload_1 */, 0/* dload_2 */, 0/* dload_3 */, 0/* aload_0 */, + 0/* aload_1 */, 0/* aload_2 */, 0/* aload_3 */, 0/* iaload */, 0/* laload */, 0/* faload */, 0/* daload */, 0/* aaload */, 0/* baload */, 0/* caload */, + 0/* saload */, 1/* istore */, 1/* lstore */, 1/* fstore */, 1/* dstore */, 1/* astore */, 0/* istore_0 */, 0/* istore_1 */, 0/* istore_2 */, + 0/* istore_3 */, 0/* lstore_0 */, 0/* lstore_1 */, 0/* lstore_2 */, 0/* lstore_3 */, 0/* fstore_0 */, 0/* fstore_1 */, 0/* fstore_2 */, 0/* fstore_3 */, + 0/* dstore_0 */, 0/* dstore_1 */, 0/* dstore_2 */, 0/* dstore_3 */, 0/* astore_0 */, 0/* astore_1 */, 0/* astore_2 */, 0/* astore_3 */, 0/* iastore */, + 0/* lastore */, 0/* fastore */, 0/* dastore */, 0/* aastore */, 0/* bastore */, 0/* castore */, 0/* sastore */, 0/* pop */, 0/* pop2 */, 0/* dup */, + 0/* dup_x1 */, 0/* dup_x2 */, 0/* dup2 */, 0/* dup2_x1 */, 0/* dup2_x2 */, 0/* swap */, 0/* iadd */, 0/* ladd */, 0/* fadd */, 0/* dadd */, 0/* isub */, + 0/* lsub */, 0/* fsub */, 0/* dsub */, 0/* imul */, 0/* lmul */, 0/* fmul */, 0/* dmul */, 0/* idiv */, 0/* ldiv */, 0/* fdiv */, 0/* ddiv */, + 0/* irem */, 0/* lrem */, 0/* frem */, 0/* drem */, 0/* ineg */, 0/* lneg */, 0/* fneg */, 0/* dneg */, 0/* ishl */, 0/* lshl */, 0/* ishr */, + 0/* lshr */, 0/* iushr */, 0/* lushr */, 0/* iand */, 0/* land */, 0/* ior */, 0/* lor */, 0/* ixor */, 0/* lxor */, 2/* iinc */, 0/* i2l */, + 0/* i2f */, 0/* i2d */, 0/* l2i */, 0/* l2f */, 0/* l2d */, 0/* f2i */, 0/* f2l */, 0/* f2d */, 0/* d2i */, 0/* d2l */, 0/* d2f */, 0/* i2b */, + 0/* i2c */, 0/* i2s */, 0/* lcmp */, 0/* fcmpl */, 0/* fcmpg */, 0/* dcmpl */, 0/* dcmpg */, 2/* ifeq */, 2/* ifne */, 2/* iflt */, 2/* ifge */, + 2/* ifgt */, 2/* ifle */, 2/* if_icmpeq */, 2/* if_icmpne */, 2/* if_icmplt */, 2/* if_icmpge */, 2/* if_icmpgt */, 2/* if_icmple */, 2/* if_acmpeq */, + 2/* if_acmpne */, 2/* goto */, 2/* jsr */, 1/* ret */, UNPREDICTABLE/* tableswitch */, UNPREDICTABLE/* lookupswitch */, 0/* ireturn */, 0/* lreturn */, + 0/* freturn */, 0/* dreturn */, 0/* areturn */, 0/* return */, 2/* getstatic */, 2/* putstatic */, 2/* getfield */, 2/* putfield */, + 2/* invokevirtual */, 2/* invokespecial */, 2/* invokestatic */, 4/* invokeinterface */, 4/* invokedynamic */, 2/* new */, 1/* newarray */, + 2/* anewarray */, 0/* arraylength */, 0/* athrow */, 2/* checkcast */, 2/* instanceof */, 0/* monitorenter */, 0/* monitorexit */, + UNPREDICTABLE/* wide */, 3/* multianewarray */, 2/* ifnull */, 2/* ifnonnull */, 4/* goto_w */, 4/* jsr_w */, 0/* breakpoint */, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, RESERVED/* impdep1 */, + RESERVED/* impdep2 */ + }; + + /** + * How the byte code operands are to be interpreted for each opcode. Indexed by opcode. TYPE_OF_OPERANDS[ILOAD] = an + * array of shorts describing the data types for the instruction. + */ + static final short[][] TYPE_OF_OPERANDS = {{}/* nop */, {}/* aconst_null */, {}/* iconst_m1 */, {}/* iconst_0 */, {}/* iconst_1 */, + {}/* iconst_2 */, {}/* iconst_3 */, {}/* iconst_4 */, {}/* iconst_5 */, {}/* lconst_0 */, {}/* lconst_1 */, {}/* fconst_0 */, {}/* fconst_1 */, + {}/* fconst_2 */, {}/* dconst_0 */, {}/* dconst_1 */, {T_BYTE}/* bipush */, {T_SHORT}/* sipush */, {T_BYTE}/* ldc */, {T_SHORT}/* ldc_w */, + {T_SHORT}/* ldc2_w */, {T_BYTE}/* iload */, {T_BYTE}/* lload */, {T_BYTE}/* fload */, {T_BYTE}/* dload */, {T_BYTE}/* aload */, {}/* iload_0 */, + {}/* iload_1 */, {}/* iload_2 */, {}/* iload_3 */, {}/* lload_0 */, {}/* lload_1 */, {}/* lload_2 */, {}/* lload_3 */, {}/* fload_0 */, {}/* fload_1 */, + {}/* fload_2 */, {}/* fload_3 */, {}/* dload_0 */, {}/* dload_1 */, {}/* dload_2 */, {}/* dload_3 */, {}/* aload_0 */, {}/* aload_1 */, {}/* aload_2 */, + {}/* aload_3 */, {}/* iaload */, {}/* laload */, {}/* faload */, {}/* daload */, {}/* aaload */, {}/* baload */, {}/* caload */, {}/* saload */, + {T_BYTE}/* istore */, {T_BYTE}/* lstore */, {T_BYTE}/* fstore */, {T_BYTE}/* dstore */, {T_BYTE}/* astore */, {}/* istore_0 */, {}/* istore_1 */, + {}/* istore_2 */, {}/* istore_3 */, {}/* lstore_0 */, {}/* lstore_1 */, {}/* lstore_2 */, {}/* lstore_3 */, {}/* fstore_0 */, {}/* fstore_1 */, + {}/* fstore_2 */, {}/* fstore_3 */, {}/* dstore_0 */, {}/* dstore_1 */, {}/* dstore_2 */, {}/* dstore_3 */, {}/* astore_0 */, {}/* astore_1 */, + {}/* astore_2 */, {}/* astore_3 */, {}/* iastore */, {}/* lastore */, {}/* fastore */, {}/* dastore */, {}/* aastore */, {}/* bastore */, + {}/* castore */, {}/* sastore */, {}/* pop */, {}/* pop2 */, {}/* dup */, {}/* dup_x1 */, {}/* dup_x2 */, {}/* dup2 */, {}/* dup2_x1 */, + {}/* dup2_x2 */, {}/* swap */, {}/* iadd */, {}/* ladd */, {}/* fadd */, {}/* dadd */, {}/* isub */, {}/* lsub */, {}/* fsub */, {}/* dsub */, + {}/* imul */, {}/* lmul */, {}/* fmul */, {}/* dmul */, {}/* idiv */, {}/* ldiv */, {}/* fdiv */, {}/* ddiv */, {}/* irem */, {}/* lrem */, + {}/* frem */, {}/* drem */, {}/* ineg */, {}/* lneg */, {}/* fneg */, {}/* dneg */, {}/* ishl */, {}/* lshl */, {}/* ishr */, {}/* lshr */, + {}/* iushr */, {}/* lushr */, {}/* iand */, {}/* land */, {}/* ior */, {}/* lor */, {}/* ixor */, {}/* lxor */, {T_BYTE, T_BYTE}/* iinc */, {}/* i2l */, + {}/* i2f */, {}/* i2d */, {}/* l2i */, {}/* l2f */, {}/* l2d */, {}/* f2i */, {}/* f2l */, {}/* f2d */, {}/* d2i */, {}/* d2l */, {}/* d2f */, + {}/* i2b */, {}/* i2c */, {}/* i2s */, {}/* lcmp */, {}/* fcmpl */, {}/* fcmpg */, {}/* dcmpl */, {}/* dcmpg */, {T_SHORT}/* ifeq */, + {T_SHORT}/* ifne */, {T_SHORT}/* iflt */, {T_SHORT}/* ifge */, {T_SHORT}/* ifgt */, {T_SHORT}/* ifle */, {T_SHORT}/* if_icmpeq */, + {T_SHORT}/* if_icmpne */, {T_SHORT}/* if_icmplt */, {T_SHORT}/* if_icmpge */, {T_SHORT}/* if_icmpgt */, {T_SHORT}/* if_icmple */, + {T_SHORT}/* if_acmpeq */, {T_SHORT}/* if_acmpne */, {T_SHORT}/* goto */, {T_SHORT}/* jsr */, {T_BYTE}/* ret */, {}/* tableswitch */, + {}/* lookupswitch */, {}/* ireturn */, {}/* lreturn */, {}/* freturn */, {}/* dreturn */, {}/* areturn */, {}/* return */, {T_SHORT}/* getstatic */, + {T_SHORT}/* putstatic */, {T_SHORT}/* getfield */, {T_SHORT}/* putfield */, {T_SHORT}/* invokevirtual */, {T_SHORT}/* invokespecial */, + {T_SHORT}/* invokestatic */, {T_SHORT, T_BYTE, T_BYTE}/* invokeinterface */, {T_SHORT, T_BYTE, T_BYTE}/* invokedynamic */, {T_SHORT}/* new */, + {T_BYTE}/* newarray */, {T_SHORT}/* anewarray */, {}/* arraylength */, {}/* athrow */, {T_SHORT}/* checkcast */, {T_SHORT}/* instanceof */, + {}/* monitorenter */, {}/* monitorexit */, {T_BYTE}/* wide */, {T_SHORT, T_BYTE}/* multianewarray */, {T_SHORT}/* ifnull */, {T_SHORT}/* ifnonnull */, + {T_INT}/* goto_w */, {T_INT}/* jsr_w */, {}/* breakpoint */, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}/* impdep1 */, {}/* impdep2 */ + }; + + /** + * Names of opcodes. Indexed by opcode. OPCODE_NAMES[ALOAD] = "aload". + */ + static final String[] OPCODE_NAMES = {"nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1", "iconst_2", "iconst_3", "iconst_4", "iconst_5", + "lconst_0", "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0", "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", "lload", + "fload", "dload", "aload", "iload_0", "iload_1", "iload_2", "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", "fload_1", "fload_2", + "fload_3", "dload_0", "dload_1", "dload_2", "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload", "laload", "faload", "daload", "aaload", + "baload", "caload", "saload", "istore", "lstore", "fstore", "dstore", "astore", "istore_0", "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", + "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2", "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", "astore_0", "astore_1", + "astore_2", "astore_3", "iastore", "lastore", "fastore", "dastore", "aastore", "bastore", "castore", "sastore", "pop", "pop2", "dup", "dup_x1", + "dup_x2", "dup2", "dup2_x1", "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub", "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", + "ldiv", "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg", "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", "iand", + "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f", "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", "i2b", "i2c", "i2s", + "lcmp", "fcmpl", "fcmpg", "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", + "if_icmpgt", "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn", "dreturn", + "areturn", "return", "getstatic", "putstatic", "getfield", "putfield", "invokevirtual", "invokespecial", "invokestatic", "invokeinterface", + "invokedynamic", "new", "newarray", "anewarray", "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", "monitorexit", "wide", + "multianewarray", "ifnull", "ifnonnull", "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, "impdep1", "impdep2"}; + + /** + * @since 6.0 + */ + public static final int OPCODE_NAMES_LENGTH = OPCODE_NAMES.length; + + /** + * Number of words consumed on operand stack by instructions. Indexed by opcode. CONSUME_STACK[FALOAD] = number of words + * consumed from the stack by a faload instruction. + */ + static final int[] CONSUME_STACK = {0/* nop */, 0/* aconst_null */, 0/* iconst_m1 */, 0/* iconst_0 */, 0/* iconst_1 */, 0/* iconst_2 */, + 0/* iconst_3 */, 0/* iconst_4 */, 0/* iconst_5 */, 0/* lconst_0 */, 0/* lconst_1 */, 0/* fconst_0 */, 0/* fconst_1 */, 0/* fconst_2 */, 0/* dconst_0 */, + 0/* dconst_1 */, 0/* bipush */, 0/* sipush */, 0/* ldc */, 0/* ldc_w */, 0/* ldc2_w */, 0/* iload */, 0/* lload */, 0/* fload */, 0/* dload */, + 0/* aload */, 0/* iload_0 */, 0/* iload_1 */, 0/* iload_2 */, 0/* iload_3 */, 0/* lload_0 */, 0/* lload_1 */, 0/* lload_2 */, 0/* lload_3 */, + 0/* fload_0 */, 0/* fload_1 */, 0/* fload_2 */, 0/* fload_3 */, 0/* dload_0 */, 0/* dload_1 */, 0/* dload_2 */, 0/* dload_3 */, 0/* aload_0 */, + 0/* aload_1 */, 0/* aload_2 */, 0/* aload_3 */, 2/* iaload */, 2/* laload */, 2/* faload */, 2/* daload */, 2/* aaload */, 2/* baload */, 2/* caload */, + 2/* saload */, 1/* istore */, 2/* lstore */, 1/* fstore */, 2/* dstore */, 1/* astore */, 1/* istore_0 */, 1/* istore_1 */, 1/* istore_2 */, + 1/* istore_3 */, 2/* lstore_0 */, 2/* lstore_1 */, 2/* lstore_2 */, 2/* lstore_3 */, 1/* fstore_0 */, 1/* fstore_1 */, 1/* fstore_2 */, 1/* fstore_3 */, + 2/* dstore_0 */, 2/* dstore_1 */, 2/* dstore_2 */, 2/* dstore_3 */, 1/* astore_0 */, 1/* astore_1 */, 1/* astore_2 */, 1/* astore_3 */, 3/* iastore */, + 4/* lastore */, 3/* fastore */, 4/* dastore */, 3/* aastore */, 3/* bastore */, 3/* castore */, 3/* sastore */, 1/* pop */, 2/* pop2 */, 1/* dup */, + 2/* dup_x1 */, 3/* dup_x2 */, 2/* dup2 */, 3/* dup2_x1 */, 4/* dup2_x2 */, 2/* swap */, 2/* iadd */, 4/* ladd */, 2/* fadd */, 4/* dadd */, 2/* isub */, + 4/* lsub */, 2/* fsub */, 4/* dsub */, 2/* imul */, 4/* lmul */, 2/* fmul */, 4/* dmul */, 2/* idiv */, 4/* ldiv */, 2/* fdiv */, 4/* ddiv */, + 2/* irem */, 4/* lrem */, 2/* frem */, 4/* drem */, 1/* ineg */, 2/* lneg */, 1/* fneg */, 2/* dneg */, 2/* ishl */, 3/* lshl */, 2/* ishr */, + 3/* lshr */, 2/* iushr */, 3/* lushr */, 2/* iand */, 4/* land */, 2/* ior */, 4/* lor */, 2/* ixor */, 4/* lxor */, 0/* iinc */, 1/* i2l */, + 1/* i2f */, 1/* i2d */, 2/* l2i */, 2/* l2f */, 2/* l2d */, 1/* f2i */, 1/* f2l */, 1/* f2d */, 2/* d2i */, 2/* d2l */, 2/* d2f */, 1/* i2b */, + 1/* i2c */, 1/* i2s */, 4/* lcmp */, 2/* fcmpl */, 2/* fcmpg */, 4/* dcmpl */, 4/* dcmpg */, 1/* ifeq */, 1/* ifne */, 1/* iflt */, 1/* ifge */, + 1/* ifgt */, 1/* ifle */, 2/* if_icmpeq */, 2/* if_icmpne */, 2/* if_icmplt */, 2 /* if_icmpge */, 2/* if_icmpgt */, 2/* if_icmple */, 2/* if_acmpeq */, + 2/* if_acmpne */, 0/* goto */, 0/* jsr */, 0/* ret */, 1/* tableswitch */, 1/* lookupswitch */, 1/* ireturn */, 2/* lreturn */, 1/* freturn */, + 2/* dreturn */, 1/* areturn */, 0/* return */, 0/* getstatic */, UNPREDICTABLE/* putstatic */, 1/* getfield */, UNPREDICTABLE/* putfield */, + UNPREDICTABLE/* invokevirtual */, UNPREDICTABLE/* invokespecial */, UNPREDICTABLE/* invokestatic */, UNPREDICTABLE/* invokeinterface */, + UNPREDICTABLE/* invokedynamic */, 0/* new */, 1/* newarray */, 1/* anewarray */, 1/* arraylength */, 1/* athrow */, 1/* checkcast */, 1/* instanceof */, + 1/* monitorenter */, 1/* monitorexit */, 0/* wide */, UNPREDICTABLE/* multianewarray */, 1/* ifnull */, 1/* ifnonnull */, 0/* goto_w */, 0/* jsr_w */, + 0/* breakpoint */, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNPREDICTABLE/* impdep1 */, UNPREDICTABLE/* impdep2 */ + }; + + /** + * Number of words produced onto operand stack by instructions. Indexed by opcode. CONSUME_STACK[DALOAD] = number of + * words consumed from the stack by a daload instruction. + */ + static final int[] PRODUCE_STACK = {0/* nop */, 1/* aconst_null */, 1/* iconst_m1 */, 1/* iconst_0 */, 1/* iconst_1 */, 1/* iconst_2 */, + 1/* iconst_3 */, 1/* iconst_4 */, 1/* iconst_5 */, 2/* lconst_0 */, 2/* lconst_1 */, 1/* fconst_0 */, 1/* fconst_1 */, 1/* fconst_2 */, 2/* dconst_0 */, + 2/* dconst_1 */, 1/* bipush */, 1/* sipush */, 1/* ldc */, 1/* ldc_w */, 2/* ldc2_w */, 1/* iload */, 2/* lload */, 1/* fload */, 2/* dload */, + 1/* aload */, 1/* iload_0 */, 1/* iload_1 */, 1/* iload_2 */, 1/* iload_3 */, 2/* lload_0 */, 2/* lload_1 */, 2/* lload_2 */, 2/* lload_3 */, + 1/* fload_0 */, 1/* fload_1 */, 1/* fload_2 */, 1/* fload_3 */, 2/* dload_0 */, 2/* dload_1 */, 2/* dload_2 */, 2/* dload_3 */, 1/* aload_0 */, + 1/* aload_1 */, 1/* aload_2 */, 1/* aload_3 */, 1/* iaload */, 2/* laload */, 1/* faload */, 2/* daload */, 1/* aaload */, 1/* baload */, 1/* caload */, + 1/* saload */, 0/* istore */, 0/* lstore */, 0/* fstore */, 0/* dstore */, 0/* astore */, 0/* istore_0 */, 0/* istore_1 */, 0/* istore_2 */, + 0/* istore_3 */, 0/* lstore_0 */, 0/* lstore_1 */, 0/* lstore_2 */, 0/* lstore_3 */, 0/* fstore_0 */, 0/* fstore_1 */, 0/* fstore_2 */, 0/* fstore_3 */, + 0/* dstore_0 */, 0/* dstore_1 */, 0/* dstore_2 */, 0/* dstore_3 */, 0/* astore_0 */, 0/* astore_1 */, 0/* astore_2 */, 0/* astore_3 */, 0/* iastore */, + 0/* lastore */, 0/* fastore */, 0/* dastore */, 0/* aastore */, 0/* bastore */, 0/* castore */, 0/* sastore */, 0/* pop */, 0/* pop2 */, 2/* dup */, + 3/* dup_x1 */, 4/* dup_x2 */, 4/* dup2 */, 5/* dup2_x1 */, 6/* dup2_x2 */, 2/* swap */, 1/* iadd */, 2/* ladd */, 1/* fadd */, 2/* dadd */, 1/* isub */, + 2/* lsub */, 1/* fsub */, 2/* dsub */, 1/* imul */, 2/* lmul */, 1/* fmul */, 2/* dmul */, 1/* idiv */, 2/* ldiv */, 1/* fdiv */, 2/* ddiv */, + 1/* irem */, 2/* lrem */, 1/* frem */, 2/* drem */, 1/* ineg */, 2/* lneg */, 1/* fneg */, 2/* dneg */, 1/* ishl */, 2/* lshl */, 1/* ishr */, + 2/* lshr */, 1/* iushr */, 2/* lushr */, 1/* iand */, 2/* land */, 1/* ior */, 2/* lor */, 1/* ixor */, 2/* lxor */, 0/* iinc */, 2/* i2l */, + 1/* i2f */, 2/* i2d */, 1/* l2i */, 1/* l2f */, 2/* l2d */, 1/* f2i */, 2/* f2l */, 2/* f2d */, 1/* d2i */, 2/* d2l */, 1/* d2f */, 1/* i2b */, + 1/* i2c */, 1/* i2s */, 1/* lcmp */, 1/* fcmpl */, 1/* fcmpg */, 1/* dcmpl */, 1/* dcmpg */, 0/* ifeq */, 0/* ifne */, 0/* iflt */, 0/* ifge */, + 0/* ifgt */, 0/* ifle */, 0/* if_icmpeq */, 0/* if_icmpne */, 0/* if_icmplt */, 0/* if_icmpge */, 0/* if_icmpgt */, 0/* if_icmple */, 0/* if_acmpeq */, + 0/* if_acmpne */, 0/* goto */, 1/* jsr */, 0/* ret */, 0/* tableswitch */, 0/* lookupswitch */, 0/* ireturn */, 0/* lreturn */, 0/* freturn */, + 0/* dreturn */, 0/* areturn */, 0/* return */, UNPREDICTABLE/* getstatic */, 0/* putstatic */, UNPREDICTABLE/* getfield */, 0/* putfield */, + UNPREDICTABLE/* invokevirtual */, UNPREDICTABLE/* invokespecial */, UNPREDICTABLE/* invokestatic */, UNPREDICTABLE/* invokeinterface */, + UNPREDICTABLE/* invokedynamic */, 1/* new */, 1/* newarray */, 1/* anewarray */, 1/* arraylength */, 1/* athrow */, 1/* checkcast */, 1/* instanceof */, + 0/* monitorenter */, 0/* monitorexit */, 0/* wide */, 1/* multianewarray */, 0/* ifnull */, 0/* ifnonnull */, 0/* goto_w */, 1/* jsr_w */, + 0/* breakpoint */, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNPREDICTABLE/* impdep1 */, UNPREDICTABLE/* impdep2 */ + }; + + /** + * Attributes and their corresponding names. + */ + public static final byte ATTR_UNKNOWN = -1; + + public static final byte ATTR_SOURCE_FILE = 0; + + public static final byte ATTR_CONSTANT_VALUE = 1; + + public static final byte ATTR_CODE = 2; + + public static final byte ATTR_EXCEPTIONS = 3; + + public static final byte ATTR_LINE_NUMBER_TABLE = 4; + + public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; + + public static final byte ATTR_INNER_CLASSES = 6; + + public static final byte ATTR_SYNTHETIC = 7; + + public static final byte ATTR_DEPRECATED = 8; + + public static final byte ATTR_PMG = 9; + + public static final byte ATTR_SIGNATURE = 10; + + public static final byte ATTR_STACK_MAP = 11; + public static final byte ATTR_RUNTIME_VISIBLE_ANNOTATIONS = 12; + public static final byte ATTR_RUNTIME_INVISIBLE_ANNOTATIONS = 13; + public static final byte ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = 14; + public static final byte ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = 15; + public static final byte ATTR_ANNOTATION_DEFAULT = 16; + public static final byte ATTR_LOCAL_VARIABLE_TYPE_TABLE = 17; + public static final byte ATTR_ENCLOSING_METHOD = 18; + public static final byte ATTR_STACK_MAP_TABLE = 19; + public static final byte ATTR_BOOTSTRAP_METHODS = 20; + public static final byte ATTR_METHOD_PARAMETERS = 21; + public static final byte ATTR_MODULE = 22; + public static final byte ATTR_MODULE_PACKAGES = 23; + public static final byte ATTR_MODULE_MAIN_CLASS = 24; + public static final byte ATTR_NEST_HOST = 25; + public static final byte ATTR_NEST_MEMBERS = 26; + public static final short KNOWN_ATTRIBUTES = 27; // count of attributes + private static final String[] ATTRIBUTE_NAMES = {"SourceFile", "ConstantValue", "Code", "Exceptions", "LineNumberTable", "LocalVariableTable", + "InnerClasses", "Synthetic", "Deprecated", "PMGClass", "Signature", "StackMap", "RuntimeVisibleAnnotations", "RuntimeInvisibleAnnotations", + "RuntimeVisibleParameterAnnotations", "RuntimeInvisibleParameterAnnotations", "AnnotationDefault", "LocalVariableTypeTable", "EnclosingMethod", + "StackMapTable", "BootstrapMethods", "MethodParameters", "Module", "ModulePackages", "ModuleMainClass", "NestHost", "NestMembers"}; + /** + * Constants used in the StackMap attribute. + */ + public static final byte ITEM_Bogus = 0; + public static final byte ITEM_Integer = 1; + public static final byte ITEM_Float = 2; + public static final byte ITEM_Double = 3; + public static final byte ITEM_Long = 4; + public static final byte ITEM_Null = 5; + public static final byte ITEM_InitObject = 6; + public static final byte ITEM_Object = 7; + public static final byte ITEM_NewObject = 8; + private static final String[] ITEM_NAMES = {"Bogus", "Integer", "Float", "Double", "Long", "Null", "InitObject", "Object", "NewObject"}; + + /** + * Constants used to identify StackMapEntry types. + * + * For those types which can specify a range, the constant names the lowest value. + */ + public static final int SAME_FRAME = 0; + + public static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; + + public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; + + public static final int CHOP_FRAME = 248; + public static final int SAME_FRAME_EXTENDED = 251; + public static final int APPEND_FRAME = 252; + public static final int FULL_FRAME = 255; + /** + * Constants that define the maximum value of those constants which store ranges. + */ + + public static final int SAME_FRAME_MAX = 63; + public static final int SAME_LOCALS_1_STACK_ITEM_FRAME_MAX = 127; + public static final int CHOP_FRAME_MAX = 250; + public static final int APPEND_FRAME_MAX = 254; + public static final byte REF_getField = 1; + + public static final byte REF_getStatic = 2; + + public static final byte REF_putField = 3; + + public static final byte REF_putStatic = 4; + public static final byte REF_invokeVirtual = 5; + public static final byte REF_invokeStatic = 6; + public static final byte REF_invokeSpecial = 7; + public static final byte REF_newInvokeSpecial = 8; + public static final byte REF_invokeInterface = 9; + /** + * The names of the reference_kinds of a CONSTANT_MethodHandle_info. + */ + private static final String[] METHODHANDLE_NAMES = {"", "getField", "getStatic", "putField", "putStatic", "invokeVirtual", "invokeStatic", "invokeSpecial", + "newInvokeSpecial", "invokeInterface"}; + + /** + * @param index + * @return the ACCESS_NAMES entry at the given index + * @since 6.0 + */ + public static String getAccessName(final int index) { + return ACCESS_NAMES[index]; + } + + /** + * + * @param index + * @return the attribute name + * @since 6.0 + */ + public static String getAttributeName(final int index) { + return ATTRIBUTE_NAMES[index]; + } + + /** + * The primitive class names corresponding to the T_XX constants, e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + * + * @param index + * @return the class name + * @since 6.0 + */ + public static String getClassTypeName(final int index) { + return CLASS_TYPE_NAMES[index]; + } + + /** + * + * @param index + * @return the CONSTANT_NAMES entry at the given index + * @since 6.0 + */ + public static String getConstantName(final int index) { + return CONSTANT_NAMES[index]; + } + + // Constants defining the behavior of the Method Handles (JVMS 5.4.3.5) + + /** + * + * @param index + * @return Number of words consumed on operand stack + * @since 6.0 + */ + public static int getConsumeStack(final int index) { + return CONSUME_STACK[index]; + } + + /** + * @since 6.0 + */ + public static Iterable getInterfacesImplementedByArrays() { + return Collections.unmodifiableList(Arrays.asList(INTERFACES_IMPLEMENTED_BY_ARRAYS)); + } + + /** + * + * @param index + * @return the item name + * @since 6.0 + */ + public static String getItemName(final int index) { + return ITEM_NAMES[index]; + } + + /** + * + * @param index + * @return the method handle name + * @since 6.0 + */ + public static String getMethodHandleName(final int index) { + return METHODHANDLE_NAMES[index]; + } + + /** + * + * @param index + * @return Number of byte code operands + * @since 6.0 + */ + public static short getNoOfOperands(final int index) { + return NO_OF_OPERANDS[index]; + } + + /** + * @since 6.0 + */ + public static String getOpcodeName(final int index) { + return OPCODE_NAMES[index]; + } + + /** + * @since 6.0 + */ + public static short getOperandType(final int opcode, final int index) { + return TYPE_OF_OPERANDS[opcode][index]; + } + + /** + * @since 6.0 + */ + public static long getOperandTypeCount(final int opcode) { + return TYPE_OF_OPERANDS[opcode].length; + } + + /** + * + * @param index + * @return Number of words produced onto operand stack + * @since 6.0 + */ + public static int getProduceStack(final int index) { + return PRODUCE_STACK[index]; + } + + /** + * + * @param index + * @return the short type name + * @since 6.0 + */ + public static String getShortTypeName(final int index) { + return SHORT_TYPE_NAMES[index]; + } + + /** + * The primitive type names corresponding to the T_XX constants, e.g., TYPE_NAMES[T_INT] = "int" + * + * @param index + * @return the type name + * @since 6.0 + */ + public static String getTypeName(final int index) { + return TYPE_NAMES[index]; + } - private Const() { } // not instantiable + private Const() { + } // not instantiable } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/ExceptionConst.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,14 +20,25 @@ package com.sun.org.apache.bcel.internal; +import jdk.xml.internal.Utils; + /** * Exception constants. + * * @since 6.0 (intended to replace the InstructionConstant interface) - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public final class ExceptionConst { /** + * Enum corresponding to the various Exception Class arrays, used by + * {@link ExceptionConst#createExceptions(EXCS, Class...)} + */ + public enum EXCS { + EXCS_CLASS_AND_INTERFACE_RESOLUTION, EXCS_FIELD_AND_METHOD_RESOLUTION, EXCS_INTERFACE_METHOD_RESOLUTION, EXCS_STRING_RESOLUTION, EXCS_ARRAY_EXCEPTION, + } + + /** * The mother of all exceptions */ public static final Class THROWABLE = Throwable.class; @@ -64,61 +75,41 @@ * Run-Time Exceptions */ public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; - public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION - = ArrayIndexOutOfBoundsException.class; + public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; + public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; + /** + * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual Machine Specification + */ + private static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = {NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, + EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR}; // Chapter 5.1 + + private static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = {NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR}; // Chapter 5.2 /** - * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual - * Machine Specification + * Empty array. */ - private static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { - NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, - EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR - }; // Chapter 5.1 - private static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { - NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR - }; // Chapter 5.2 private static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) - private static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; - // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) - private static final Class[] EXCS_ARRAY_EXCEPTION = { - NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION - }; /** - * Enum corresponding to the various Exception Class arrays, - * used by {@link ExceptionConst#createExceptions(EXCS, Class...)} + * Empty array. */ - public enum EXCS { - EXCS_CLASS_AND_INTERFACE_RESOLUTION, - EXCS_FIELD_AND_METHOD_RESOLUTION, - EXCS_INTERFACE_METHOD_RESOLUTION, - EXCS_STRING_RESOLUTION, - EXCS_ARRAY_EXCEPTION, - } + private static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; - // helper method to merge exception class arrays - private static Class[] mergeExceptions(final Class[] input, final Class ... extraClasses) { - final int extraLen = extraClasses == null ? 0 : extraClasses.length; - final Class[] excs = new Class[input.length + extraLen]; - System.arraycopy(input, 0, excs, 0, input.length); - if (extraLen > 0) { - System.arraycopy(extraClasses, 0, excs, input.length, extraLen); - } - return excs; - } + // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) + private static final Class[] EXCS_ARRAY_EXCEPTION = {NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION}; /** * Creates a copy of the specified Exception Class array combined with any additional Exception classes. + * * @param type the basic array type * @param extraClasses additional classes, if any * @return the merged array */ - public static Class[] createExceptions(final EXCS type, final Class ... extraClasses) { + public static Class[] createExceptions(final EXCS type, final Class... extraClasses) { switch (type) { case EXCS_CLASS_AND_INTERFACE_RESOLUTION: return mergeExceptions(EXCS_CLASS_AND_INTERFACE_RESOLUTION, extraClasses); @@ -135,5 +126,8 @@ } } - + // helper method to merge exception class arrays + private static Class[] mergeExceptions(final Class[] input, final Class... extraClasses) { + return Utils.arraysAppend(input, extraClasses); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * AALOAD - Load reference from array - *
    Stack: ..., arrayref, index -> value
    * + *
    + * Stack: ..., arrayref, index -> value
    + * 
    */ public class AALOAD extends ArrayInstruction implements StackProducer { - /** Load reference from array + /** + * Load reference from array */ public AALOAD() { super(com.sun.org.apache.bcel.internal.Const.AALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * AASTORE - Store into reference array - *
    Stack: ..., arrayref, index, value -> ...
    + * AASTORE - Store into reference array * + *
    + * Stack: ..., arrayref, index, value -> ...
    + * 
    */ public class AASTORE extends ArrayInstruction implements StackConsumer { - /** Store into reference array + /** + * Store into reference array */ public AASTORE() { super(com.sun.org.apache.bcel.internal.Const.AASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ACONST_NULL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * ACONST_NULL - Push null reference - *
    Stack: ... -> ..., null
    * + *
    + * Stack: ... -> ..., null
    + * 
    */ public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction { @@ -35,28 +37,25 @@ super(com.sun.org.apache.bcel.internal.Const.ACONST_NULL, (short) 1); } - - /** @return Type.NULL - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.NULL; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitPushInstruction(this); v.visitTypedInstruction(this); v.visitACONST_NULL(this); } + + /** + * @return Type.NULL + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.NULL; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AllocationInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,7 +23,6 @@ /** * Denote family of instructions that allocates space in the heap. - * */ public interface AllocationInstruction { } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -20,43 +20,40 @@ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Const; - /** * ALOAD - Load reference from local variable - *
    Stack: ... -> ..., objectref
    * + *
    + * Stack: ... -> ..., objectref
    + * 
    * @LastModified: Jan 2020 */ public class ALOAD extends LoadInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ALOAD() { - super(Const.ALOAD, Const.ALOAD_0); + super(com.sun.org.apache.bcel.internal.Const.ALOAD, com.sun.org.apache.bcel.internal.Const.ALOAD_0); } - - /** Load reference from local variable + /** + * Load reference from local variable + * * @param n index of local variable */ public ALOAD(final int n) { - super(Const.ALOAD, Const.ALOAD_0, n); + super(com.sun.org.apache.bcel.internal.Const.ALOAD, com.sun.org.apache.bcel.internal.Const.ALOAD_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitALOAD(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ANEWARRAY.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,43 +24,32 @@ import com.sun.org.apache.bcel.internal.ExceptionConst; /** - * ANEWARRAY - Create new array of references - *
    Stack: ..., count -> ..., arrayref
    + * ANEWARRAY - Create new array of references * + *
    + * Stack: ..., count -> ..., arrayref
    + * 
    */ -public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, - ExceptionThrower, StackConsumer, StackProducer { +public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, ExceptionThrower, StackConsumer, StackProducer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ANEWARRAY() { } - public ANEWARRAY(final int index) { super(com.sun.org.apache.bcel.internal.Const.ANEWARRAY, index); } - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, - ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLoadClass(this); v.visitAllocationInstruction(this); v.visitExceptionThrower(this); @@ -70,13 +59,17 @@ v.visitANEWARRAY(this); } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); + } @Override - public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + public ObjectType getLoadClassType(final ConstantPoolGen cpg) { Type t = getType(cpg); if (t instanceof ArrayType) { t = ((ArrayType) t).getBasicType(); } - return (t instanceof ObjectType) ? (ObjectType) t : null; + return t instanceof ObjectType ? (ObjectType) t : null; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationElementValueGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,61 +30,48 @@ /** * @since 6.0 */ -public class AnnotationElementValueGen extends ElementValueGen -{ +public class AnnotationElementValueGen extends ElementValueGen { // For annotation element values, this is the annotation private final AnnotationEntryGen a; - public AnnotationElementValueGen(final AnnotationEntryGen a, final ConstantPoolGen cpool) - { + public AnnotationElementValueGen(final AnnotationElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + super(ANNOTATION, cpool); + a = new AnnotationEntryGen(value.getAnnotationEntry(), cpool, copyPoolEntries); + } + + public AnnotationElementValueGen(final AnnotationEntryGen a, final ConstantPoolGen cpool) { super(ANNOTATION, cpool); this.a = a; } - public AnnotationElementValueGen(final int type, final AnnotationEntryGen annotation, - final ConstantPoolGen cpool) - { + public AnnotationElementValueGen(final int type, final AnnotationEntryGen annotation, final ConstantPoolGen cpool) { super(type, cpool); if (type != ANNOTATION) { - throw new IllegalArgumentException( - "Only element values of type annotation can be built with this ctor - type specified: " + type); + throw new IllegalArgumentException("Only element values of type annotation can be built with this ctor - type specified: " + type); } this.a = annotation; } - public AnnotationElementValueGen(final AnnotationElementValue value, - final ConstantPoolGen cpool, final boolean copyPoolEntries) - { - super(ANNOTATION, cpool); - a = new AnnotationEntryGen(value.getAnnotationEntry(), cpool, copyPoolEntries); - } - @Override - public void dump(final DataOutputStream dos) throws IOException - { + public void dump(final DataOutputStream dos) throws IOException { dos.writeByte(super.getElementValueType()); // u1 type of value (ANNOTATION == '@') a.dump(dos); } - @Override - public String stringifyValue() - { - throw new UnsupportedOperationException("Not implemented yet"); + public AnnotationEntryGen getAnnotation() { + return a; } /** * Return immutable variant of this AnnotationElementValueGen */ @Override - public ElementValue getElementValue() - { - return new AnnotationElementValue(super.getElementValueType(), - a.getAnnotation(), - getConstantPool().getConstantPool()); + public ElementValue getElementValue() { + return new AnnotationElementValue(super.getElementValueType(), a.getAnnotation(), getConstantPool().getConstantPool()); } - public AnnotationEntryGen getAnnotation() - { - return a; + @Override + public String stringifyValue() { + throw new UnsupportedOperationException("Not implemented yet"); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/AnnotationEntryGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -43,173 +43,25 @@ * @LastModified: Jan 2020 */ public class AnnotationEntryGen { - private int typeIndex; - - private List evs; - - private final ConstantPoolGen cpool; - - private boolean isRuntimeVisible = false; - - /** - * Here we are taking a fixed annotation of type Annotation and building a - * modifiable AnnotationGen object. If the pool passed in is for a different - * class file, then copyPoolEntries should have been passed as true as that - * will force us to do a deep copy of the annotation and move the cpool - * entries across. We need to copy the type and the element name value pairs - * and the visibility. - */ - public AnnotationEntryGen(final AnnotationEntry a, final ConstantPoolGen cpool, - final boolean copyPoolEntries) { - this.cpool = cpool; - if (copyPoolEntries) { - typeIndex = cpool.addUtf8(a.getAnnotationType()); - } else { - typeIndex = a.getAnnotationTypeIndex(); - } - isRuntimeVisible = a.isRuntimeVisible(); - evs = copyValues(a.getElementValuePairs(), cpool, copyPoolEntries); - } - - private List copyValues(final ElementValuePair[] in, final ConstantPoolGen cpool, - final boolean copyPoolEntries) { - final List out = new ArrayList<>(); - for (final ElementValuePair nvp : in) { - out.add(new ElementValuePairGen(nvp, cpool, copyPoolEntries)); - } - return out; - } - - private AnnotationEntryGen(final ConstantPoolGen cpool) { - this.cpool = cpool; - } - - /** - * Retrieve an immutable version of this AnnotationGen - */ - public AnnotationEntry getAnnotation() { - final AnnotationEntry a = new AnnotationEntry(typeIndex, cpool.getConstantPool(), - isRuntimeVisible); - for (final ElementValuePairGen element : evs) { - a.addElementNameValuePair(element.getElementNameValuePair()); - } - return a; - } - - public AnnotationEntryGen(final ObjectType type, - final List elements, final boolean vis, - final ConstantPoolGen cpool) { - this.cpool = cpool; - this.typeIndex = cpool.addUtf8(type.getSignature()); - evs = elements; - isRuntimeVisible = vis; - } - - public static AnnotationEntryGen read(final DataInput dis, - final ConstantPoolGen cpool, final boolean b) throws IOException { - final AnnotationEntryGen a = new AnnotationEntryGen(cpool); - a.typeIndex = dis.readUnsignedShort(); - final int elemValuePairCount = dis.readUnsignedShort(); - for (int i = 0; i < elemValuePairCount; i++) { - final int nidx = dis.readUnsignedShort(); - a.addElementNameValuePair(new ElementValuePairGen(nidx, - ElementValueGen.readElementValue(dis, cpool), cpool)); - } - a.isRuntimeVisible(b); - return a; - } - - public void dump(final DataOutputStream dos) throws IOException { - dos.writeShort(typeIndex); // u2 index of type name in cpool - dos.writeShort(evs.size()); // u2 element_value pair count - for (final ElementValuePairGen envp : evs) { - envp.dump(dos); - } - } - - public void addElementNameValuePair(final ElementValuePairGen evp) { - if (evs == null) { - evs = new ArrayList<>(); - } - evs.add(evp); - } - public int getTypeIndex() { - return typeIndex; - } - - public final String getTypeSignature() { - // ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex); - final ConstantUtf8 utf8 = (ConstantUtf8) cpool - .getConstant(typeIndex/* c.getNameIndex() */); - return utf8.getBytes(); - } - - public final String getTypeName() { - return getTypeSignature();// BCELBUG: Should I use this instead? - // Utility.signatureToString(getTypeSignature()); - } + static final AnnotationEntryGen[] EMPTY_ARRAY = {}; /** - * Returns list of ElementNameValuePair objects - */ - public List getValues() { - return evs; - } - - @Override - public String toString() { - final StringBuilder s = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber - s.append("AnnotationGen:[").append(getTypeName()).append(" #").append(evs.size()).append(" {"); - for (int i = 0; i < evs.size(); i++) { - s.append(evs.get(i)); - if (i + 1 < evs.size()) { - s.append(","); - } - } - s.append("}]"); - return s.toString(); - } - - public String toShortString() { - final StringBuilder s = new StringBuilder(); - s.append("@").append(getTypeName()).append("("); - for (int i = 0; i < evs.size(); i++) { - s.append(evs.get(i)); - if (i + 1 < evs.size()) { - s.append(","); - } - } - s.append(")"); - return s.toString(); - } - - private void isRuntimeVisible(final boolean b) { - isRuntimeVisible = b; - } - - public boolean isRuntimeVisible() { - return isRuntimeVisible; - } - - - /** - * Converts a list of AnnotationGen objects into a set of attributes - * that can be attached to the class file. + * Converts a list of AnnotationGen objects into a set of attributes that can be attached to the class file. * - * @param cp The constant pool gen where we can create the necessary name refs + * @param cp The constant pool gen where we can create the necessary name refs * @param annotationEntryGens An array of AnnotationGen objects */ static Attribute[] getAnnotationAttributes(final ConstantPoolGen cp, final AnnotationEntryGen[] annotationEntryGens) { if (annotationEntryGens.length == 0) { - return new Attribute[0]; + return Attribute.EMPTY_ARRAY; } try { int countVisible = 0; int countInvisible = 0; - // put the annotations in the right output stream + // put the annotations in the right output stream for (final AnnotationEntryGen a : annotationEntryGens) { if (a.isRuntimeVisible()) { countVisible++; @@ -220,8 +72,7 @@ final ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream(); final ByteArrayOutputStream riaBytes = new ByteArrayOutputStream(); - try (DataOutputStream rvaDos = new DataOutputStream(rvaBytes); - DataOutputStream riaDos = new DataOutputStream(riaBytes)) { + try (DataOutputStream rvaDos = new DataOutputStream(rvaBytes); DataOutputStream riaDos = new DataOutputStream(riaBytes)) { rvaDos.writeShort(countVisible); riaDos.writeShort(countInvisible); @@ -251,17 +102,15 @@ final List newAttributes = new ArrayList<>(); if (rvaData.length > 2) { - newAttributes.add( - new RuntimeVisibleAnnotations(rvaIndex, rvaData.length, - new DataInputStream(new ByteArrayInputStream(rvaData)), cp.getConstantPool())); + newAttributes + .add(new RuntimeVisibleAnnotations(rvaIndex, rvaData.length, new DataInputStream(new ByteArrayInputStream(rvaData)), cp.getConstantPool())); } if (riaData.length > 2) { newAttributes.add( - new RuntimeInvisibleAnnotations(riaIndex, riaData.length, - new DataInputStream(new ByteArrayInputStream(riaData)), cp.getConstantPool())); + new RuntimeInvisibleAnnotations(riaIndex, riaData.length, new DataInputStream(new ByteArrayInputStream(riaData)), cp.getConstantPool())); } - return newAttributes.toArray(new Attribute[newAttributes.size()]); + return newAttributes.toArray(Attribute.EMPTY_ARRAY); } catch (final IOException e) { System.err.println("IOException whilst processing annotations"); e.printStackTrace(); @@ -269,15 +118,12 @@ return null; } - /** - * Annotations against a class are stored in one of four attribute kinds: - * - RuntimeVisibleParameterAnnotations - * - RuntimeInvisibleParameterAnnotations + * Annotations against a class are stored in one of four attribute kinds: - RuntimeVisibleParameterAnnotations - + * RuntimeInvisibleParameterAnnotations */ - static Attribute[] getParameterAnnotationAttributes( - final ConstantPoolGen cp, - final List[] /*Array of lists, array size depends on #params */vec) { + static Attribute[] getParameterAnnotationAttributes(final ConstantPoolGen cp, + final List[] /* Array of lists, array size depends on #params */ vec) { final int[] visCount = new int[vec.length]; int totalVisCount = 0; final int[] invisCount = new int[vec.length]; @@ -338,25 +184,158 @@ } final List newAttributes = new ArrayList<>(); if (totalVisCount > 0) { - newAttributes - .add(new RuntimeVisibleParameterAnnotations(rvaIndex, - rvaData.length, - new DataInputStream(new ByteArrayInputStream(rvaData)), - cp.getConstantPool())); + newAttributes.add(new RuntimeVisibleParameterAnnotations(rvaIndex, rvaData.length, new DataInputStream(new ByteArrayInputStream(rvaData)), + cp.getConstantPool())); } if (totalInvisCount > 0) { - newAttributes - .add(new RuntimeInvisibleParameterAnnotations(riaIndex, - riaData.length, - new DataInputStream(new ByteArrayInputStream(riaData)), - cp.getConstantPool())); + newAttributes.add(new RuntimeInvisibleParameterAnnotations(riaIndex, riaData.length, new DataInputStream(new ByteArrayInputStream(riaData)), + cp.getConstantPool())); } - return newAttributes.toArray(new Attribute[newAttributes.size()]); + return newAttributes.toArray(Attribute.EMPTY_ARRAY); } catch (final IOException e) { - System.err.println("IOException whilst processing parameter annotations." + - e.getMessage()); + System.err.println("IOException whilst processing parameter annotations"); + e.printStackTrace(); } return null; } + public static AnnotationEntryGen read(final DataInput dis, final ConstantPoolGen cpool, final boolean b) throws IOException { + final AnnotationEntryGen a = new AnnotationEntryGen(cpool); + a.typeIndex = dis.readUnsignedShort(); + final int elemValuePairCount = dis.readUnsignedShort(); + for (int i = 0; i < elemValuePairCount; i++) { + final int nidx = dis.readUnsignedShort(); + a.addElementNameValuePair(new ElementValuePairGen(nidx, ElementValueGen.readElementValue(dis, cpool), cpool)); + } + a.isRuntimeVisible(b); + return a; + } + + private int typeIndex; + + private List evs; + + private final ConstantPoolGen cpool; + + private boolean isRuntimeVisible; + + /** + * Here we are taking a fixed annotation of type Annotation and building a modifiable AnnotationGen object. If the pool + * passed in is for a different class file, then copyPoolEntries should have been passed as true as that will force us + * to do a deep copy of the annotation and move the cpool entries across. We need to copy the type and the element name + * value pairs and the visibility. + */ + public AnnotationEntryGen(final AnnotationEntry a, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + this.cpool = cpool; + if (copyPoolEntries) { + typeIndex = cpool.addUtf8(a.getAnnotationType()); + } else { + typeIndex = a.getAnnotationTypeIndex(); + } + isRuntimeVisible = a.isRuntimeVisible(); + evs = copyValues(a.getElementValuePairs(), cpool, copyPoolEntries); + } + + private AnnotationEntryGen(final ConstantPoolGen cpool) { + this.cpool = cpool; + } + + public AnnotationEntryGen(final ObjectType type, final List elements, final boolean vis, final ConstantPoolGen cpool) { + this.cpool = cpool; + this.typeIndex = cpool.addUtf8(type.getSignature()); + evs = elements; + isRuntimeVisible = vis; + } + + public void addElementNameValuePair(final ElementValuePairGen evp) { + if (evs == null) { + evs = new ArrayList<>(); + } + evs.add(evp); + } + + private List copyValues(final ElementValuePair[] in, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + final List out = new ArrayList<>(); + for (final ElementValuePair nvp : in) { + out.add(new ElementValuePairGen(nvp, cpool, copyPoolEntries)); + } + return out; + } + + public void dump(final DataOutputStream dos) throws IOException { + dos.writeShort(typeIndex); // u2 index of type name in cpool + dos.writeShort(evs.size()); // u2 element_value pair count + for (final ElementValuePairGen envp : evs) { + envp.dump(dos); + } + } + + /** + * Retrieve an immutable version of this AnnotationGen + */ + public AnnotationEntry getAnnotation() { + final AnnotationEntry a = new AnnotationEntry(typeIndex, cpool.getConstantPool(), isRuntimeVisible); + for (final ElementValuePairGen element : evs) { + a.addElementNameValuePair(element.getElementNameValuePair()); + } + return a; + } + + public int getTypeIndex() { + return typeIndex; + } + + public final String getTypeName() { + return getTypeSignature();// BCELBUG: Should I use this instead? + // Utility.signatureToString(getTypeSignature()); + } + + public final String getTypeSignature() { + // ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex); + final ConstantUtf8 utf8 = (ConstantUtf8) cpool.getConstant(typeIndex/* c.getNameIndex() */); + return utf8.getBytes(); + } + + /** + * Returns list of ElementNameValuePair objects + */ + public List getValues() { + return evs; + } + + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + private void isRuntimeVisible(final boolean b) { + isRuntimeVisible = b; + } + + public String toShortString() { + final StringBuilder s = new StringBuilder(); + s.append("@").append(getTypeName()).append("("); + for (int i = 0; i < evs.size(); i++) { + s.append(evs.get(i)); + if (i + 1 < evs.size()) { + s.append(","); + } + } + s.append(")"); + return s.toString(); + } + + @Override + public String toString() { + final StringBuilder s = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber + s.append("AnnotationGen:[").append(getTypeName()).append(" #").append(evs.size()).append(" {"); + for (int i = 0; i < evs.size(); i++) { + s.append(evs.get(i)); + if (i + 1 < evs.size()) { + s.append(","); + } + } + s.append("}]"); + return s.toString(); + } + } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARETURN.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,9 +22,11 @@ package com.sun.org.apache.bcel.internal.generic; /** - * ARETURN - Return reference from method - *
    Stack: ..., objectref -> <empty>
    + * ARETURN - Return reference from method * + *
    + * Stack: ..., objectref -> <empty>
    + * 
    */ public class ARETURN extends ReturnInstruction { @@ -35,17 +37,14 @@ super(com.sun.org.apache.bcel.internal.Const.ARETURN); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArithmeticInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,19 +25,15 @@ /** * Super class for the family of arithmetic instructions. - * */ -public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction, - StackProducer, StackConsumer { +public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction, StackProducer, StackConsumer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ArithmeticInstruction() { } - /** * @param opcode of instruction */ @@ -45,55 +41,55 @@ super(opcode, (short) 1); } - - /** @return type associated with the instruction + /** + * @return type associated with the instruction */ @Override - public Type getType( final ConstantPoolGen cp ) { - final short _opcode = super.getOpcode(); - switch (_opcode) { - case Const.DADD: - case Const.DDIV: - case Const.DMUL: - case Const.DNEG: - case Const.DREM: - case Const.DSUB: - return Type.DOUBLE; - case Const.FADD: - case Const.FDIV: - case Const.FMUL: - case Const.FNEG: - case Const.FREM: - case Const.FSUB: - return Type.FLOAT; - case Const.IADD: - case Const.IAND: - case Const.IDIV: - case Const.IMUL: - case Const.INEG: - case Const.IOR: - case Const.IREM: - case Const.ISHL: - case Const.ISHR: - case Const.ISUB: - case Const.IUSHR: - case Const.IXOR: - return Type.INT; - case Const.LADD: - case Const.LAND: - case Const.LDIV: - case Const.LMUL: - case Const.LNEG: - case Const.LOR: - case Const.LREM: - case Const.LSHL: - case Const.LSHR: - case Const.LSUB: - case Const.LUSHR: - case Const.LXOR: - return Type.LONG; - default: // Never reached - throw new ClassGenException("Unknown type " + _opcode); + public Type getType(final ConstantPoolGen cp) { + final short opcode = super.getOpcode(); + switch (opcode) { + case Const.DADD: + case Const.DDIV: + case Const.DMUL: + case Const.DNEG: + case Const.DREM: + case Const.DSUB: + return Type.DOUBLE; + case Const.FADD: + case Const.FDIV: + case Const.FMUL: + case Const.FNEG: + case Const.FREM: + case Const.FSUB: + return Type.FLOAT; + case Const.IADD: + case Const.IAND: + case Const.IDIV: + case Const.IMUL: + case Const.INEG: + case Const.IOR: + case Const.IREM: + case Const.ISHL: + case Const.ISHR: + case Const.ISUB: + case Const.IUSHR: + case Const.IXOR: + return Type.INT; + case Const.LADD: + case Const.LAND: + case Const.LDIV: + case Const.LMUL: + case Const.LNEG: + case Const.LOR: + case Const.LREM: + case Const.LSHL: + case Const.LSHR: + case Const.LSUB: + case Const.LUSHR: + case Const.LXOR: + return Type.LONG; + default: // Never reached + throw new ClassGenException("Unknown type " + opcode); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayElementValueGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -32,25 +32,33 @@ /** * @since 6.0 */ -public class ArrayElementValueGen extends ElementValueGen -{ +public class ArrayElementValueGen extends ElementValueGen { // J5TODO: Should we make this an array or a list? A list would be easier to // modify ... private final List evalues; - public ArrayElementValueGen(final ConstantPoolGen cp) - { + /** + * @param value + * @param cpool + */ + public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + super(ARRAY, cpool); + evalues = new ArrayList<>(); + final ElementValue[] in = value.getElementValuesArray(); + for (final ElementValue element : in) { + evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries)); + } + } + + public ArrayElementValueGen(final ConstantPoolGen cp) { super(ARRAY, cp); evalues = new ArrayList<>(); } - public ArrayElementValueGen(final int type, final ElementValue[] datums, - final ConstantPoolGen cpool) - { + public ArrayElementValueGen(final int type, final ElementValue[] datums, final ConstantPoolGen cpool) { super(type, cpool); if (type != ARRAY) { - throw new IllegalArgumentException( - "Only element values of type array can be built with this ctor - type specified: " + type); + throw new IllegalArgumentException("Only element values of type array can be built with this ctor - type specified: " + type); } this.evalues = new ArrayList<>(); for (final ElementValue datum : datums) { @@ -58,50 +66,42 @@ } } + public void addElement(final ElementValueGen gen) { + evalues.add(gen); + } + + @Override + public void dump(final DataOutputStream dos) throws IOException { + dos.writeByte(super.getElementValueType()); // u1 type of value (ARRAY == '[') + dos.writeShort(evalues.size()); + for (final ElementValueGen element : evalues) { + element.dump(dos); + } + } + /** * Return immutable variant of this ArrayElementValueGen */ @Override - public ElementValue getElementValue() - { + public ElementValue getElementValue() { final ElementValue[] immutableData = new ElementValue[evalues.size()]; int i = 0; for (final ElementValueGen element : evalues) { immutableData[i++] = element.getElementValue(); } - return new ArrayElementValue(super.getElementValueType(), - immutableData, - getConstantPool().getConstantPool()); + return new ArrayElementValue(super.getElementValueType(), immutableData, getConstantPool().getConstantPool()); } - /** - * @param value - * @param cpool - */ - public ArrayElementValueGen(final ArrayElementValue value, final ConstantPoolGen cpool, - final boolean copyPoolEntries) - { - super(ARRAY, cpool); - evalues = new ArrayList<>(); - final ElementValue[] in = value.getElementValuesArray(); - for (final ElementValue element : in) { - evalues.add(ElementValueGen.copy(element, cpool, copyPoolEntries)); - } + public List getElementValues() { + return evalues; } - @Override - public void dump(final DataOutputStream dos) throws IOException - { - dos.writeByte(super.getElementValueType()); // u1 type of value (ARRAY == '[') - dos.writeShort(evalues.size()); - for (final ElementValueGen element : evalues) { - element.dump(dos); - } + public int getElementValuesSize() { + return evalues.size(); } @Override - public String stringifyValue() - { + public String stringifyValue() { final StringBuilder sb = new StringBuilder(); sb.append("["); String comma = ""; @@ -113,19 +113,4 @@ sb.append("]"); return sb.toString(); } - - public List getElementValues() - { - return evalues; - } - - public int getElementValuesSize() - { - return evalues.size(); - } - - public void addElement(final ElementValueGen gen) - { - evalues.add(gen); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,19 +25,15 @@ /** * Super class for instructions dealing with array access such as IALOAD. - * */ -public abstract class ArrayInstruction extends Instruction implements ExceptionThrower, - TypedInstruction { +public abstract class ArrayInstruction extends Instruction implements ExceptionThrower, TypedInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ArrayInstruction() { } - /** * @param opcode of instruction */ @@ -45,45 +41,44 @@ super(opcode, (short) 1); } - @Override public Class[] getExceptions() { return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_ARRAY_EXCEPTION); } - - /** @return type associated with the instruction + /** + * @return type associated with the instruction */ @Override - public Type getType( final ConstantPoolGen cp ) { - final short _opcode = super.getOpcode(); - switch (_opcode) { - case com.sun.org.apache.bcel.internal.Const.IALOAD: - case com.sun.org.apache.bcel.internal.Const.IASTORE: - return Type.INT; - case com.sun.org.apache.bcel.internal.Const.CALOAD: - case com.sun.org.apache.bcel.internal.Const.CASTORE: - return Type.CHAR; - case com.sun.org.apache.bcel.internal.Const.BALOAD: - case com.sun.org.apache.bcel.internal.Const.BASTORE: - return Type.BYTE; - case com.sun.org.apache.bcel.internal.Const.SALOAD: - case com.sun.org.apache.bcel.internal.Const.SASTORE: - return Type.SHORT; - case com.sun.org.apache.bcel.internal.Const.LALOAD: - case com.sun.org.apache.bcel.internal.Const.LASTORE: - return Type.LONG; - case com.sun.org.apache.bcel.internal.Const.DALOAD: - case com.sun.org.apache.bcel.internal.Const.DASTORE: - return Type.DOUBLE; - case com.sun.org.apache.bcel.internal.Const.FALOAD: - case com.sun.org.apache.bcel.internal.Const.FASTORE: - return Type.FLOAT; - case com.sun.org.apache.bcel.internal.Const.AALOAD: - case com.sun.org.apache.bcel.internal.Const.AASTORE: - return Type.OBJECT; - default: - throw new ClassGenException("Unknown case in switch" + _opcode); + public Type getType(final ConstantPoolGen cp) { + final short opcode = super.getOpcode(); + switch (opcode) { + case com.sun.org.apache.bcel.internal.Const.IALOAD: + case com.sun.org.apache.bcel.internal.Const.IASTORE: + return Type.INT; + case com.sun.org.apache.bcel.internal.Const.CALOAD: + case com.sun.org.apache.bcel.internal.Const.CASTORE: + return Type.CHAR; + case com.sun.org.apache.bcel.internal.Const.BALOAD: + case com.sun.org.apache.bcel.internal.Const.BASTORE: + return Type.BYTE; + case com.sun.org.apache.bcel.internal.Const.SALOAD: + case com.sun.org.apache.bcel.internal.Const.SASTORE: + return Type.SHORT; + case com.sun.org.apache.bcel.internal.Const.LALOAD: + case com.sun.org.apache.bcel.internal.Const.LASTORE: + return Type.LONG; + case com.sun.org.apache.bcel.internal.Const.DALOAD: + case com.sun.org.apache.bcel.internal.Const.DASTORE: + return Type.DOUBLE; + case com.sun.org.apache.bcel.internal.Const.FALOAD: + case com.sun.org.apache.bcel.internal.Const.FASTORE: + return Type.FLOAT; + case com.sun.org.apache.bcel.internal.Const.AALOAD: + case com.sun.org.apache.bcel.internal.Const.AASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Unknown case in switch" + opcode); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ARRAYLENGTH.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,43 +23,40 @@ import com.sun.org.apache.bcel.internal.ExceptionConst; /** - * ARRAYLENGTH - Get length of array - *
    Stack: ..., arrayref -> ..., length
    + * ARRAYLENGTH - Get length of array * - * @LastModified: Jun 2019 + *
    + * Stack: ..., arrayref -> ..., length
    + * 
    + * @LastModified: Feb 2023 */ -public class ARRAYLENGTH extends Instruction - implements ExceptionThrower, StackProducer, StackConsumer /* since 6.0 */ { +public class ARRAYLENGTH extends Instruction implements ExceptionThrower, StackProducer, StackConsumer /* since 6.0 */ { - /** Get length of array + /** + * Get length of array */ public ARRAYLENGTH() { super(com.sun.org.apache.bcel.internal.Const.ARRAYLENGTH, (short) 1); } - - /** @return exceptions this instruction may cause - */ - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.NULL_POINTER_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitStackProducer(this); v.visitARRAYLENGTH(this); } + + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.NULL_POINTER_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ArrayType.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,56 +24,55 @@ /** * Denotes array type, such as int[][] - * */ public final class ArrayType extends ReferenceType { - private int dimensions; - private Type basicType; - + private final int dimensions; + private final Type basicType; /** * Convenience constructor for array type, e.g. int[] * * @param type array type, e.g. T_INT + * @param dimensions array dimensions */ public ArrayType(final byte type, final int dimensions) { this(BasicType.getType(type), dimensions); } - /** * Convenience constructor for reference array type, e.g. Object[] * - * @param class_name complete name of class (java.lang.String, e.g.) + * @param className complete name of class (java.lang.String, e.g.) + * @param dimensions array dimensions */ - public ArrayType(final String class_name, final int dimensions) { - this(ObjectType.getInstance(class_name), dimensions); + public ArrayType(final String className, final int dimensions) { + this(ObjectType.getInstance(className), dimensions); } - /** * Constructor for array of given type * * @param type type of array (may be an array itself) + * @param dimensions array dimensions */ public ArrayType(final Type type, final int dimensions) { super(Const.T_ARRAY, ""); - if ((dimensions < 1) || (dimensions > Const.MAX_BYTE)) { + if (dimensions < 1 || dimensions > Const.MAX_BYTE) { throw new ClassGenException("Invalid number of dimensions: " + dimensions); } switch (type.getType()) { - case Const.T_ARRAY: - final ArrayType array = (ArrayType) type; - this.dimensions = dimensions + array.dimensions; - basicType = array.basicType; - break; - case Const.T_VOID: - throw new ClassGenException("Invalid type: void[]"); - default: // Basic type or reference - this.dimensions = dimensions; - basicType = type; - break; + case Const.T_ARRAY: + final ArrayType array = (ArrayType) type; + this.dimensions = dimensions + array.dimensions; + basicType = array.basicType; + break; + case Const.T_VOID: + throw new ClassGenException("Invalid type: void[]"); + default: // Basic type or reference + this.dimensions = dimensions; + basicType = type; + break; } final StringBuilder buf = new StringBuilder(); for (int i = 0; i < this.dimensions; i++) { @@ -83,6 +82,17 @@ super.setSignature(buf.toString()); } + /** + * @return true if both type objects refer to the same array type. + */ + @Override + public boolean equals(final Object type) { + if (type instanceof ArrayType) { + final ArrayType array = (ArrayType) type; + return array.dimensions == dimensions && array.basicType.equals(basicType); + } + return false; + } /** * @return basic type of array, i.e., for int[][][] the basic type is int @@ -91,6 +101,24 @@ return basicType; } + /** + * Gets the name of referenced class. + * + * @return name of referenced class. + * @since 6.7.0 + */ + @Override + @Deprecated + public String getClassName() { + return signature; + } + + /** + * @return number of dimensions of array + */ + public int getDimensions() { + return dimensions; + } /** * @return element type of array, i.e., for int[][][] the element type is int[][] @@ -102,30 +130,11 @@ return new ArrayType(basicType, dimensions - 1); } - - /** @return number of dimensions of array - */ - public int getDimensions() { - return dimensions; - } - - - /** @return a hash code value for the object. + /** + * @return a hash code value for the object. */ @Override public int hashCode() { return basicType.hashCode() ^ dimensions; } - - - /** @return true if both type objects refer to the same array type. - */ - @Override - public boolean equals( final Object _type ) { - if (_type instanceof ArrayType) { - final ArrayType array = (ArrayType) _type; - return (array.dimensions == dimensions) && array.basicType.equals(basicType); - } - return false; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -19,43 +19,40 @@ */ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Const; - /** * ASTORE - Store reference into local variable - *
    Stack ..., objectref -> ... 
    * + *
    + * Stack ..., objectref -> ...
    + * 
    * @LastModified: Jan 2020 */ public class ASTORE extends StoreInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ASTORE() { - super(Const.ASTORE, Const.ASTORE_0); + super(com.sun.org.apache.bcel.internal.Const.ASTORE, com.sun.org.apache.bcel.internal.Const.ASTORE_0); } - - /** Store reference into local variable + /** + * Store reference into local variable + * * @param n index of local variable */ public ASTORE(final int n) { - super(Const.ASTORE, Const.ASTORE_0, n); + super(com.sun.org.apache.bcel.internal.Const.ASTORE, com.sun.org.apache.bcel.internal.Const.ASTORE_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitASTORE(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ATHROW.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,43 +23,39 @@ import com.sun.org.apache.bcel.internal.ExceptionConst; /** - * ATHROW - Throw exception - *
    Stack: ..., objectref -> objectref
    + * ATHROW - Throw exception * - * @LastModified: Jan 2020 + *
    + * Stack: ..., objectref -> objectref
    + * 
    */ public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower { /** - * Throw exception + * Throw exception */ public ATHROW() { super(com.sun.org.apache.bcel.internal.Const.ATHROW, (short) 1); } - - /** @return exceptions this instruction may cause - */ - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.THROWABLE - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitUnconditionalBranch(this); v.visitExceptionThrower(this); v.visitATHROW(this); } + + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.THROWABLE}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,28 +22,28 @@ /** * BALOAD - Load byte or boolean from array - *
    Stack: ..., arrayref, index -> ..., value
    * + *
    + * Stack: ..., arrayref, index -> ..., value
    + * 
    */ public class BALOAD extends ArrayInstruction implements StackProducer { - /** Load byte or boolean from array + /** + * Load byte or boolean from array */ public BALOAD() { super(com.sun.org.apache.bcel.internal.Const.BALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BasicType.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,63 +24,61 @@ /** * Denotes basic type such as int. - * */ public final class BasicType extends Type { + // @since 6.0 no longer final + public static BasicType getType(final byte type) { + switch (type) { + case Const.T_VOID: + return VOID; + case Const.T_BOOLEAN: + return BOOLEAN; + case Const.T_BYTE: + return BYTE; + case Const.T_SHORT: + return SHORT; + case Const.T_CHAR: + return CHAR; + case Const.T_INT: + return INT; + case Const.T_LONG: + return LONG; + case Const.T_DOUBLE: + return DOUBLE; + case Const.T_FLOAT: + return FLOAT; + default: + throw new ClassGenException("Invalid type: " + type); + } + } + /** - * Constructor for basic types such as int, long, `void' + * Constructor for basic types such as int, long, 'void' * * @param type one of T_INT, T_BOOLEAN, ..., T_VOID * @see Const */ BasicType(final byte type) { super(type, Const.getShortTypeName(type)); - if ((type < Const.T_BOOLEAN) || (type > Const.T_VOID)) { + if (type < Const.T_BOOLEAN || type > Const.T_VOID) { throw new ClassGenException("Invalid type: " + type); } } - - // @since 6.0 no longer final - public static BasicType getType( final byte type ) { - switch (type) { - case Const.T_VOID: - return VOID; - case Const.T_BOOLEAN: - return BOOLEAN; - case Const.T_BYTE: - return BYTE; - case Const.T_SHORT: - return SHORT; - case Const.T_CHAR: - return CHAR; - case Const.T_INT: - return INT; - case Const.T_LONG: - return LONG; - case Const.T_DOUBLE: - return DOUBLE; - case Const.T_FLOAT: - return FLOAT; - default: - throw new ClassGenException("Invalid type: " + type); - } - } - - - /** @return a hash code value for the object. + /** + * @return true if both type objects refer to the same type */ @Override - public int hashCode() { - return super.getType(); + public boolean equals(final Object type) { + return type instanceof BasicType && ((BasicType) type).getType() == this.getType(); } - - /** @return true if both type objects refer to the same type + /** + * @return a hash code value for the object. */ @Override - public boolean equals( final Object _type ) { - return (_type instanceof BasicType) ? ((BasicType) _type).getType() == this.getType() : false; + public int hashCode() { + return super.getType(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,29 +21,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * BASTORE - Store into byte or boolean array - *
    Stack: ..., arrayref, index, value -> ...
    + * BASTORE - Store into byte or boolean array * + *
    + * Stack: ..., arrayref, index, value -> ...
    + * 
    */ public class BASTORE extends ArrayInstruction implements StackConsumer { - /** Store byte or boolean into array + /** + * Store byte or boolean into array */ public BASTORE() { super(com.sun.org.apache.bcel.internal.Const.BASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BIPUSH.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,87 +27,79 @@ /** * BIPUSH - Push byte on stack * - *
    Stack: ... -> ..., value
    - * + *
    + * Stack: ... -> ..., value
    + * 
    */ public class BIPUSH extends Instruction implements ConstantPushInstruction { private byte b; - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ BIPUSH() { } - - /** Push byte on stack + /** + * Push byte on stack */ public BIPUSH(final byte b) { super(com.sun.org.apache.bcel.internal.Const.BIPUSH, (short) 2); this.b = b; } - /** - * Dump instruction as byte code to stream out. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object */ @Override - public void dump( final DataOutputStream out ) throws IOException { - super.dump(out); - out.writeByte(b); + public void accept(final Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitBIPUSH(this); } - /** - * @return mnemonic for instruction + * Dump instruction as byte code to stream out. */ @Override - public String toString( final boolean verbose ) { - return super.toString(verbose) + " " + b; + public void dump(final DataOutputStream out) throws IOException { + super.dump(out); + out.writeByte(b); } - /** - * Read needed data (e.g. index) from file. + * @return Type.BYTE */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - super.setLength(2); - b = bytes.readByte(); + public Type getType(final ConstantPoolGen cp) { + return Type.BYTE; } - @Override public Number getValue() { return Integer.valueOf(b); } - - /** @return Type.BYTE + /** + * Read needed data (e.g. index) from file. */ @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.BYTE; + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(2); + b = bytes.readByte(); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object + * @return mnemonic for instruction */ @Override - public void accept( final Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitBIPUSH(this); + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + b; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchHandle.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,10 +21,8 @@ package com.sun.org.apache.bcel.internal.generic; /** - * BranchHandle is returned by specialized InstructionList.append() whenever a - * BranchInstruction is appended. This is useful when the target of this - * instruction is not known at time of creation and must be set later - * via setTarget(). + * BranchHandle is returned by specialized InstructionList.append() whenever a BranchInstruction is appended. This is + * useful when the target of this instruction is not known at time of creation and must be set later via setTarget(). * * @see InstructionHandle * @see Instruction @@ -32,83 +30,75 @@ */ public final class BranchHandle extends InstructionHandle { + /** + * Factory method. + */ + static BranchHandle getBranchHandle(final BranchInstruction i) { + return new BranchHandle(i); + } + // This is also a cache in case the InstructionHandle#swapInstruction() method is used // See BCEL-273 private BranchInstruction bi; // An alias in fact, but saves lots of casts - private BranchHandle(final BranchInstruction i) { super(i); bi = i; } - /** Factory method. - */ - static BranchHandle getBranchHandle( final BranchInstruction i ) { - return new BranchHandle(i); - } - - - /* Override InstructionHandle methods: delegate to branch instruction. - * Through this overriding all access to the private i_position field should - * be prevented. + /* + * Override InstructionHandle methods: delegate to branch instruction. Through this overriding all access to the private + * i_position field should be prevented. */ @Override public int getPosition() { return bi.getPosition(); } + /** + * @return target of instruction. + */ + public InstructionHandle getTarget() { + return bi.getTarget(); + } + + /** + * Set new contents. Old instruction is disposed and may not be used anymore. + */ + @Override // This is only done in order to apply the additional type check; could be merged with super impl. + public void setInstruction(final Instruction i) { // TODO could be package-protected? + super.setInstruction(i); + if (!(i instanceof BranchInstruction)) { + throw new ClassGenException("Assigning " + i + " to branch handle which is not a branch instruction"); + } + bi = (BranchInstruction) i; + } @Override - void setPosition( final int pos ) { + void setPosition(final int pos) { // Original code: i_position = bi.position = pos; bi.setPosition(pos); super.setPosition(pos); } - - @Override - protected int updatePosition( final int offset, final int max_offset ) { - final int x = bi.updatePosition(offset, max_offset); - super.setPosition(bi.getPosition()); - return x; - } - - /** * Pass new target to instruction. */ - public void setTarget( final InstructionHandle ih ) { + public void setTarget(final InstructionHandle ih) { bi.setTarget(ih); } - - /** - * Update target of instruction. - */ - public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { - bi.updateTarget(old_ih, new_ih); - } - - - /** - * @return target of instruction. - */ - public InstructionHandle getTarget() { - return bi.getTarget(); + @Override + protected int updatePosition(final int offset, final int maxOffset) { + final int x = bi.updatePosition(offset, maxOffset); + super.setPosition(bi.getPosition()); + return x; } - /** - * Set new contents. Old instruction is disposed and may not be used anymore. + * Update target of instruction. */ - @Override // This is only done in order to apply the additional type check; could be merged with super impl. - public void setInstruction( final Instruction i ) { // TODO could be package-protected? - super.setInstruction(i); - if (!(i instanceof BranchInstruction)) { - throw new ClassGenException("Assigning " + i - + " to branch handle which is not a branch instruction"); - } - bi = (BranchInstruction) i; + public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) { + bi.updateTarget(oldIh, newIh); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -25,149 +25,94 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; /** - * Abstract super class for branching instructions like GOTO, IFEQ, etc.. - * Branch instructions may have a variable length, namely GOTO, JSR, - * LOOKUPSWITCH and TABLESWITCH. + * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch instructions may have a variable + * length, namely GOTO, JSR, LOOKUPSWITCH and TABLESWITCH. * * @see InstructionList - * @LastModified: July 2020 + * @LastModified: Feb 2023 */ public abstract class BranchInstruction extends Instruction implements InstructionTargeter { - private int index; // Branch target relative to this instruction - private InstructionHandle target; // Target object in instruction list - private int position; // Byte code offset - /** - * Empty constructor needed for the Class.newInstance() statement in - * Instruction.readInstruction(). Not to be used otherwise. + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen, LineNumberGen */ - BranchInstruction() { + static void notifyTarget(final InstructionHandle oldIh, final InstructionHandle newIh, final InstructionTargeter t) { + if (oldIh != null) { + oldIh.removeTargeter(t); + } + if (newIh != null) { + newIh.addTargeter(t); + } } - - /** Common super constructor - * @param opcode Instruction opcode - * @param target instruction to branch to + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - protected BranchInstruction(final short opcode, final InstructionHandle target) { - super(opcode, (short) 3); - setTarget(target); - } - + @Deprecated + protected int index; // Branch target relative to this instruction /** - * Dump instruction as byte code to stream out. - * @param out Output stream + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - index = getTargetOffset(); - if (!isValidShort(index)) { - throw new ClassGenException("Branch target offset too large for short: " + index); - } - out.writeShort(index); // May be negative, i.e., point backwards - } - + @Deprecated + protected InstructionHandle target; // Target object in instruction list /** - * @param _target branch target - * @return the offset to `target' relative to this instruction + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - protected int getTargetOffset( final InstructionHandle _target ) { - if (_target == null) { - throw new ClassGenException("Target of " + super.toString(true) - + " is invalid null handle"); - } - final int t = _target.getPosition(); - if (t < 0) { - throw new ClassGenException("Invalid branch target position offset for " - + super.toString(true) + ":" + t + ":" + _target); - } - return t - position; - } - + @Deprecated + protected int position; // Byte code offset /** - * @return the offset to this instruction's target + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ - protected int getTargetOffset() { - return getTargetOffset(target); + BranchInstruction() { } - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. + * Common super constructor * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length + * @param opcode Instruction opcode + * @param target instruction to branch to */ - protected int updatePosition( final int offset, final int max_offset ) { - position += offset; - return 0; + protected BranchInstruction(final short opcode, final InstructionHandle target) { + super(opcode, (short) 3); + setTarget(target); } - /** - * Long output format: - * - * <position in byte code> - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" - * "<"<target instruction>">" "@"<branch target offset> - * - * @param verbose long/short format switch - * @return mnemonic for instruction + * @return true, if ih is target of this instruction */ @Override - public String toString( final boolean verbose ) { - final String s = super.toString(verbose); - String t = "null"; - if (verbose) { - if (target != null) { - if (target.getInstruction() == this) { - t = ""; - } else if (target.getInstruction() == null) { - t = ""; - } else { - // I'm more interested in the address of the target then - // the instruction located there. - //t = target.getInstruction().toString(false); // Avoid circles - t = "" + target.getPosition(); - } - } - } else { - if (target != null) { - index = target.getPosition(); - // index = getTargetOffset(); crashes if positions haven't been set - // t = "" + (index + position); - t = "" + index; - } - } - return s + " -> " + t; + public boolean containsTarget(final InstructionHandle ih) { + return target == ih; } + /** + * Inform target that it's not targeted anymore. + */ + @Override + void dispose() { + setTarget(null); + index = -1; + position = -1; + } /** - * Read needed data (e.g. index) from file. Conversion to a InstructionHandle - * is done in InstructionList(byte[]). + * Dump instruction as byte code to stream out. * - * @param bytes input stream - * @param wide wide prefix? - * @see InstructionList + * @param out Output stream */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - super.setLength(3); - index = bytes.readShort(); + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + index = getTargetOffset(); + if (!isValidShort(index)) { + throw new ClassGenException("Branch target offset too large for short: " + index); + } + out.writeShort(index); // May be negative, i.e., point backwards } - /** * @return target offset in byte code */ @@ -175,6 +120,13 @@ return index; } + /** + * @return the position + * @since 6.0 + */ + protected int getPosition() { + return position; + } /** * @return target of branch instruction @@ -183,51 +135,55 @@ return target; } - /** - * Set branch target - * @param target branch target + * @return the offset to this instruction's target */ - public void setTarget( final InstructionHandle target ) { - notifyTarget(this.target, target, this); - this.target = target; + protected int getTargetOffset() { + return getTargetOffset(target); } - /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen, LineNumberGen + * @param target branch target + * @return the offset to 'target' relative to this instruction */ - static void notifyTarget( final InstructionHandle old_ih, final InstructionHandle new_ih, - final InstructionTargeter t ) { - if (old_ih != null) { - old_ih.removeTargeter(t); + protected int getTargetOffset(final InstructionHandle target) { + if (target == null) { + throw new ClassGenException("Target of " + super.toString(true) + " is invalid null handle"); } - if (new_ih != null) { - new_ih.addTargeter(t); + final int t = target.getPosition(); + if (t < 0) { + throw new ClassGenException("Invalid branch target position offset for " + super.toString(true) + ":" + t + ":" + target); } + return t - position; } - /** - * @param old_ih old target - * @param new_ih new target + * Read needed data (e.g. index) from file. Conversion to a InstructionHandle is done in InstructionList(byte[]). + * + * @param bytes input stream + * @param wide wide prefix? + * @see InstructionList */ @Override - public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { - if (target == old_ih) { - setTarget(new_ih); - } else { - throw new ClassGenException("Not targeting " + old_ih + ", but " + target); - } + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(3); + index = bytes.readShort(); } + /** + * @param index the index to set + * @since 6.0 + */ + protected void setIndex(final int index) { + this.index = index; + } /** - * @return true, if ih is target of this instruction + * @param position the position to set + * @since 6.0 */ - @Override - public boolean containsTarget( final InstructionHandle ih ) { - return target == ih; + protected void setPosition(final int position) { + this.position = position; } /** @@ -249,40 +205,74 @@ } /** - * Inform target that it's not targeted anymore. + * Set branch target + * + * @param target branch target */ - @Override - void dispose() { - setTarget(null); - index = -1; - position = -1; + public void setTarget(final InstructionHandle target) { + notifyTarget(this.target, target, this); + this.target = target; } - /** - * @return the position - * @since 6.0 + * Long output format: + * + * <position in byte code> <name of opcode> "["<opcode number>"]" "("<length of instruction>")" + * "<"<target instruction>">" "@"<branch target offset> + * + * @param verbose long/short format switch + * @return mnemonic for instruction */ - protected int getPosition() { - return position; + @Override + public String toString(final boolean verbose) { + final String s = super.toString(verbose); + String t = "null"; + if (target != null) { + if (verbose) { + if (target.getInstruction() == this) { + t = ""; + } else if (target.getInstruction() == null) { + t = ""; + } else { + // I'm more interested in the address of the target then + // the instruction located there. + // t = target.getInstruction().toString(false); // Avoid circles + t = "" + target.getPosition(); + } + } else { + index = target.getPosition(); + // index = getTargetOffset(); crashes if positions haven't been set + // t = "" + (index + position); + t = "" + index; + } + } + return s + " -> " + t; } - /** - * @param position the position to set - * @since 6.0 + * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable + * length instructions 'setPositions' performs multiple passes over the instruction list to calculate the correct (byte) + * positions and offsets by calling this function. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param maxOffset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length */ - protected void setPosition(final int position) { - this.position = position; + protected int updatePosition(final int offset, final int maxOffset) { + position += offset; + return 0; } - /** - * @param index the index to set - * @since 6.0 + * @param oldIh old target + * @param newIh new target */ - protected void setIndex(final int index) { - this.index = index; + @Override + public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) { + if (target != oldIh) { + throw new ClassGenException("Not targeting " + oldIh + ", but " + target); + } + setTarget(newIh); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/BREAKPOINT.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,7 +22,6 @@ /** * BREAKPOINT, JVM dependent, ignored by default - * */ public class BREAKPOINT extends Instruction { @@ -30,17 +29,14 @@ super(com.sun.org.apache.bcel.internal.Const.BREAKPOINT, (short) 1); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitBREAKPOINT(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * CALOAD - Load char from array - *
    Stack: ..., arrayref, index -> ..., value
    * + *
    + * Stack: ..., arrayref, index -> ..., value
    + * 
    */ public class CALOAD extends ArrayInstruction implements StackProducer { - /** Load char from array + /** + * Load char from array */ public CALOAD() { super(com.sun.org.apache.bcel.internal.Const.CALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * CASTORE - Store into char array - *
    Stack: ..., arrayref, index, value -> ...
    + * CASTORE - Store into char array * + *
    + * Stack: ..., arrayref, index, value -> ...
    + * 
    */ public class CASTORE extends ArrayInstruction implements StackConsumer { - /** Store char into array + /** + * Store char into array */ public CASTORE() { super(com.sun.org.apache.bcel.internal.Const.CASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CHECKCAST.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,57 +25,36 @@ /** * CHECKCAST - Check whether object is of given type - *
    Stack: ..., objectref -> ..., objectref
    * + *
    + * Stack: ..., objectref -> ..., objectref
    + * 
    */ -public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, - StackConsumer { +public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, StackConsumer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ CHECKCAST() { } - - /** Check whether object is of given type + /** + * Check whether object is of given type + * * @param index index to class in constant pool */ public CHECKCAST(final int index) { super(com.sun.org.apache.bcel.internal.Const.CHECKCAST, index); } - - /** @return exceptions this instruction may cause - */ - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, - ExceptionConst.CLASS_CAST_EXCEPTION); - } - - - @Override - public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return (t instanceof ObjectType) ? (ObjectType) t : null; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLoadClass(this); v.visitExceptionThrower(this); v.visitStackProducer(this); @@ -84,4 +63,21 @@ v.visitCPInstruction(this); v.visitCHECKCAST(this); } + + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, ExceptionConst.CLASS_CAST_EXCEPTION); + } + + @Override + public ObjectType getLoadClassType(final ConstantPoolGen cpg) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return t instanceof ObjectType ? (ObjectType) t : null; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassElementValueGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,59 +31,40 @@ /** * @since 6.0 */ -public class ClassElementValueGen extends ElementValueGen -{ +public class ClassElementValueGen extends ElementValueGen { // For primitive types and string type, this points to the value entry in // the cpool // For 'class' this points to the class entry in the cpool - private int idx; + private final int idx; - protected ClassElementValueGen(final int typeIdx, final ConstantPoolGen cpool) - { + public ClassElementValueGen(final ClassElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + super(CLASS, cpool); + if (copyPoolEntries) { + // idx = cpool.addClass(value.getClassString()); + idx = cpool.addUtf8(value.getClassString()); + } else { + idx = value.getIndex(); + } + } + + protected ClassElementValueGen(final int typeIdx, final ConstantPoolGen cpool) { super(ElementValueGen.CLASS, cpool); this.idx = typeIdx; } - public ClassElementValueGen(final ObjectType t, final ConstantPoolGen cpool) - { + public ClassElementValueGen(final ObjectType t, final ConstantPoolGen cpool) { super(ElementValueGen.CLASS, cpool); // this.idx = cpool.addClass(t); idx = cpool.addUtf8(t.getSignature()); } - /** - * Return immutable variant of this ClassElementValueGen - */ @Override - public ElementValue getElementValue() - { - return new ClassElementValue(super.getElementValueType(), - idx, - getConstantPool().getConstantPool()); - } - - public ClassElementValueGen(final ClassElementValue value, final ConstantPoolGen cpool, - final boolean copyPoolEntries) - { - super(CLASS, cpool); - if (copyPoolEntries) - { - // idx = cpool.addClass(value.getClassString()); - idx = cpool.addUtf8(value.getClassString()); - } - else - { - idx = value.getIndex(); - } - } - - public int getIndex() - { - return idx; + public void dump(final DataOutputStream dos) throws IOException { + dos.writeByte(super.getElementValueType()); // u1 kind of value + dos.writeShort(idx); } - public String getClassString() - { + public String getClassString() { final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); return cu8.getBytes(); // ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); @@ -92,16 +73,20 @@ // return utf8.getBytes(); } + /** + * Return immutable variant of this ClassElementValueGen + */ @Override - public String stringifyValue() - { - return getClassString(); + public ElementValue getElementValue() { + return new ClassElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); + } + + public int getIndex() { + return idx; } @Override - public void dump(final DataOutputStream dos) throws IOException - { - dos.writeByte(super.getElementValueType()); // u1 kind of value - dos.writeShort(idx); + public String stringifyValue() { + return getClassString(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGenException.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,19 +22,15 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Thrown on internal errors. Extends RuntimeException so it hasn't to be declared - * in the throws clause every time. - * + * Thrown on internal exceptions. */ public class ClassGenException extends RuntimeException { private static final long serialVersionUID = 7247369755051242791L; public ClassGenException() { - super(); } - public ClassGenException(final String s) { super(s); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,12 +20,13 @@ package com.sun.org.apache.bcel.internal.generic; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.AccessFlags; -import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; import com.sun.org.apache.bcel.internal.classfile.Annotations; import com.sun.org.apache.bcel.internal.classfile.Attribute; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; @@ -35,106 +36,79 @@ import com.sun.org.apache.bcel.internal.classfile.RuntimeInvisibleAnnotations; import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleAnnotations; import com.sun.org.apache.bcel.internal.classfile.SourceFile; +import com.sun.org.apache.bcel.internal.classfile.Utility; import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * Template class for building up a java class. May be initialized with an - * existing java class (file). + * Template class for building up a java class. May be initialized with an existing java class (file). * * @see JavaClass - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public class ClassGen extends AccessFlags implements Cloneable { - /* Corresponds to the fields found in a JavaClass object. - */ - private String className; - private String superClassName; - private final String fileName; - private int classNameIndex = -1; - private int superclass_name_index = -1; - private int major = Const.MAJOR_1_1; - private int minor = Const.MINOR_1_1; - private ConstantPoolGen cp; // Template for building up constant pool - // ArrayLists instead of arrays to gather fields, methods, etc. - private final List fieldList = new ArrayList<>(); - private final List methodList = new ArrayList<>(); - private final List attributeList = new ArrayList<>(); - private final List interfaceList = new ArrayList<>(); - private final List annotationList = new ArrayList<>(); - private static BCELComparator bcelComparator = new BCELComparator() { @Override - public boolean equals( final Object o1, final Object o2 ) { + public boolean equals(final Object o1, final Object o2) { final ClassGen THIS = (ClassGen) o1; final ClassGen THAT = (ClassGen) o2; return Objects.equals(THIS.getClassName(), THAT.getClassName()); } - @Override - public int hashCode( final Object o ) { + public int hashCode(final Object o) { final ClassGen THIS = (ClassGen) o; return THIS.getClassName().hashCode(); } }; - - /** Convenience constructor to set up some important values initially. - * - * @param className fully qualified class name - * @param superClassName fully qualified superclass name - * @param fileName source file name - * @param accessFlags access qualifiers - * @param interfaces implemented interfaces - * @param cp constant pool to use + /** + * @return Comparison strategy object */ - public ClassGen(final String className, final String superClassName, final String fileName, final int accessFlags, - final String[] interfaces, final ConstantPoolGen cp) { - super(accessFlags); - this.className = className; - this.superClassName = superClassName; - this.fileName = fileName; - this.cp = cp; - // Put everything needed by default into the constant pool and the vectors - if (fileName != null) { - addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(fileName), cp - .getConstantPool())); - } - classNameIndex = cp.addClass(className); - superclass_name_index = cp.addClass(superClassName); - if (interfaces != null) { - for (final String interface1 : interfaces) { - addInterface(interface1); - } - } + public static BCELComparator getComparator() { + return bcelComparator; } - - /** Convenience constructor to set up some important values initially. - * - * @param className fully qualified class name - * @param superClassName fully qualified superclass name - * @param fileName source file name - * @param accessFlags access qualifiers - * @param interfaces implemented interfaces + /** + * @param comparator Comparison strategy object */ - public ClassGen(final String className, final String superClassName, final String fileName, final int accessFlags, - final String[] interfaces) { - this(className, superClassName, fileName, accessFlags, interfaces, - new ConstantPoolGen()); + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; } + /* + * Corresponds to the fields found in a JavaClass object. + */ + private String className; + private String superClassName; + private final String fileName; + private int classNameIndex = -1; + private int superclassNameIndex = -1; + private int major = Const.MAJOR_1_1; + private int minor = Const.MINOR_1_1; + private ConstantPoolGen cp; // Template for building up constant pool + // ArrayLists instead of arrays to gather fields, methods, etc. + private final List fieldList = new ArrayList<>(); + private final List methodList = new ArrayList<>(); + + private final List attributeList = new ArrayList<>(); + + private final List interfaceList = new ArrayList<>(); + + private final List annotationList = new ArrayList<>(); + + private List observers; /** * Initialize with existing class. + * * @param clazz JavaClass object (e.g. read from file) */ public ClassGen(final JavaClass clazz) { super(clazz.getAccessFlags()); classNameIndex = clazz.getClassNameIndex(); - superclass_name_index = clazz.getSuperclassNameIndex(); + superclassNameIndex = clazz.getSuperclassNameIndex(); className = clazz.getClassName(); superClassName = clazz.getSuperclassName(); fileName = clazz.getSourceFileName(); @@ -144,189 +118,142 @@ final Attribute[] attributes = clazz.getAttributes(); // J5TODO: Could make unpacking lazy, done on first reference final AnnotationEntryGen[] annotations = unpackAnnotations(attributes); - final Method[] methods = clazz.getMethods(); - final Field[] fields = clazz.getFields(); - final String[] interfaces = clazz.getInterfaceNames(); - for (final String interface1 : interfaces) { - addInterface(interface1); - } + Collections.addAll(interfaceList, clazz.getInterfaceNames()); for (final Attribute attribute : attributes) { if (!(attribute instanceof Annotations)) { addAttribute(attribute); } } - for (final AnnotationEntryGen annotation : annotations) { - addAnnotationEntry(annotation); - } - for (final Method method : methods) { - addMethod(method); - } - for (final Field field : fields) { - addField(field); - } + Collections.addAll(annotationList, annotations); + Collections.addAll(methodList, clazz.getMethods()); + Collections.addAll(fieldList, clazz.getFields()); } /** - * Look for attributes representing annotations and unpack them. + * Convenience constructor to set up some important values initially. + * + * @param className fully qualified class name + * @param superClassName fully qualified superclass name + * @param fileName source file name + * @param accessFlags access qualifiers + * @param interfaces implemented interfaces */ - private AnnotationEntryGen[] unpackAnnotations(final Attribute[] attrs) - { - final List annotationGenObjs = new ArrayList<>(); - for (final Attribute attr : attrs) { - if (attr instanceof RuntimeVisibleAnnotations) - { - final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr; - final AnnotationEntry[] annos = rva.getAnnotationEntries(); - for (final AnnotationEntry a : annos) { - annotationGenObjs.add(new AnnotationEntryGen(a, - getConstantPool(), false)); - } - } - else - if (attr instanceof RuntimeInvisibleAnnotations) - { - final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr; - final AnnotationEntry[] annos = ria.getAnnotationEntries(); - for (final AnnotationEntry a : annos) { - annotationGenObjs.add(new AnnotationEntryGen(a, - getConstantPool(), false)); - } - } - } - return annotationGenObjs.toArray(new AnnotationEntryGen[annotationGenObjs.size()]); + public ClassGen(final String className, final String superClassName, final String fileName, final int accessFlags, final String[] interfaces) { + this(className, superClassName, fileName, accessFlags, interfaces, new ConstantPoolGen()); } - /** - * @return the (finally) built up Java class object. + * Convenience constructor to set up some important values initially. + * + * @param className fully qualified class name + * @param superClassName fully qualified superclass name + * @param fileName source file name + * @param accessFlags access qualifiers + * @param interfaces implemented interfaces + * @param cp constant pool to use */ - public JavaClass getJavaClass() { - final int[] interfaces = getInterfaces(); - final Field[] fields = getFields(); - final Method[] methods = getMethods(); - Attribute[] attributes = null; - if (annotationList.isEmpty()) { - attributes = getAttributes(); - } else { - // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' - final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries()); - attributes = new Attribute[attributeList.size()+annAttributes.length]; - attributeList.toArray(attributes); - System.arraycopy(annAttributes,0,attributes,attributeList.size(),annAttributes.length); + public ClassGen(final String className, final String superClassName, final String fileName, final int accessFlags, final String[] interfaces, + final ConstantPoolGen cp) { + super(accessFlags); + this.className = className; + this.superClassName = superClassName; + this.fileName = fileName; + this.cp = cp; + // Put everything needed by default into the constant pool and the vectors + if (fileName != null) { + addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(fileName), cp.getConstantPool())); + } + classNameIndex = cp.addClass(className); + superclassNameIndex = cp.addClass(superClassName); + if (interfaces != null) { + Collections.addAll(interfaceList, interfaces); } - // Must be last since the above calls may still add something to it - final ConstantPool _cp = this.cp.getFinalConstantPool(); - return new JavaClass(classNameIndex, superclass_name_index, fileName, major, minor, - super.getAccessFlags(), _cp, interfaces, fields, methods, attributes); } - - /** - * Add an interface to this class, i.e., this class has to implement it. - * @param name interface to implement (fully qualified class name) - */ - public void addInterface( final String name ) { - interfaceList.add(name); + public void addAnnotationEntry(final AnnotationEntryGen a) { + annotationList.add(a); } - /** - * Remove an interface from this class. - * @param name interface to remove (fully qualified name) + * Add an attribute to this class. + * + * @param a attribute to add */ - public void removeInterface( final String name ) { - interfaceList.remove(name); + public void addAttribute(final Attribute a) { + attributeList.add(a); } - /** - * @return major version number of class file - */ - public int getMajor() { - return major; - } - - - /** Set major version number of class file, default value is 45 (JDK 1.1) - * @param major major version number - */ - public void setMajor( final int major ) { // TODO could be package-protected - only called by test code - this.major = major; - } - - - /** Set minor version number of class file, default value is 3 (JDK 1.1) - * @param minor minor version number + * Convenience method. + * + * Add an empty constructor to this class that does nothing but calling super(). + * + * @param accessFlags rights for constructor */ - public void setMinor( final int minor ) { // TODO could be package-protected - only called by test code - this.minor = minor; + public void addEmptyConstructor(final int accessFlags) { + final InstructionList il = new InstructionList(); + il.append(InstructionConst.THIS); // Push 'this' + il.append(new INVOKESPECIAL(cp.addMethodref(superClassName, Const.CONSTRUCTOR_NAME, "()V"))); + il.append(InstructionConst.RETURN); + final MethodGen mg = new MethodGen(accessFlags, Type.VOID, Type.NO_ARGS, null, Const.CONSTRUCTOR_NAME, className, il, cp); + mg.setMaxStack(1); + addMethod(mg.getMethod()); } /** - * @return minor version number of class file + * Add a field to this class. + * + * @param f field to add */ - public int getMinor() { - return minor; + public void addField(final Field f) { + fieldList.add(f); } - /** - * Add an attribute to this class. - * @param a attribute to add + * Add an interface to this class, i.e., this class has to implement it. + * + * @param name interface to implement (fully qualified class name) */ - public void addAttribute( final Attribute a ) { - attributeList.add(a); - } - - public void addAnnotationEntry(final AnnotationEntryGen a) { - annotationList.add(a); + public void addInterface(final String name) { + interfaceList.add(name); } - /** * Add a method to this class. + * * @param m method to add */ - public void addMethod( final Method m ) { + public void addMethod(final Method m) { methodList.add(m); } - /** - * Convenience method. - * - * Add an empty constructor to this class that does nothing but calling super(). - * @param access_flags rights for constructor + * Add observer for this object. */ - public void addEmptyConstructor( final int access_flags ) { - final InstructionList il = new InstructionList(); - il.append(InstructionConst.THIS); // Push `this' - il.append(new INVOKESPECIAL(cp.addMethodref(superClassName, "", "()V"))); - il.append(InstructionConst.RETURN); - final MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "", - className, il, cp); - mg.setMaxStack(1); - addMethod(mg.getMethod()); + public void addObserver(final ClassObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); } - - /** - * Add a field to this class. - * @param f field to add - */ - public void addField( final Field f ) { - fieldList.add(f); + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - - public boolean containsField( final Field f ) { + public boolean containsField(final Field f) { return fieldList.contains(f); } - - /** @return field object with given name, or null + /** + * @return field object with given name, or null */ - public Field containsField( final String name ) { + public Field containsField(final String name) { for (final Field f : fieldList) { if (f.getName().equals(name)) { return f; @@ -335,10 +262,10 @@ return null; } - - /** @return method object with given name and signature, or null + /** + * @return method object with given name and signature, or null */ - public Method containsMethod( final String name, final String signature ) { + public Method containsMethod(final String name, final String signature) { for (final Method m : methodList) { if (m.getName().equals(name) && m.getSignature().equals(signature)) { return m; @@ -347,264 +274,272 @@ return null; } - /** - * Remove an attribute from this class. - * @param a attribute to remove - */ - public void removeAttribute( final Attribute a ) { - attributeList.remove(a); - } - - - /** - * Remove a method from this class. - * @param m method to remove - */ - public void removeMethod( final Method m ) { - methodList.remove(m); - } - - - /** Replace given method with new one. If the old one does not exist - * add the new_ method to the class anyway. + * Return value as defined by given BCELComparator strategy. By default two ClassGen objects are said to be equal when + * their class names are equal. + * + * @see Object#equals(Object) */ - public void replaceMethod( final Method old, final Method new_ ) { - if (new_ == null) { - throw new ClassGenException("Replacement method must not be null"); - } - final int i = methodList.indexOf(old); - if (i < 0) { - methodList.add(new_); - } else { - methodList.set(i, new_); - } + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); } - - /** Replace given field with new one. If the old one does not exist - * add the new_ field to the class anyway. - */ - public void replaceField( final Field old, final Field new_ ) { - if (new_ == null) { - throw new ClassGenException("Replacement method must not be null"); - } - final int i = fieldList.indexOf(old); - if (i < 0) { - fieldList.add(new_); - } else { - fieldList.set(i, new_); - } + // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? + public AnnotationEntryGen[] getAnnotationEntries() { + return annotationList.toArray(AnnotationEntryGen.EMPTY_ARRAY); } - - /** - * Remove a field to this class. - * @param f field to remove - */ - public void removeField( final Field f ) { - fieldList.remove(f); + public Attribute[] getAttributes() { + return attributeList.toArray(Attribute.EMPTY_ARRAY); } - public String getClassName() { return className; } - - public String getSuperclassName() { - return superClassName; - } - - - public String getFileName() { - return fileName; - } - - - public void setClassName( final String name ) { - className = name.replace('/', '.'); - classNameIndex = cp.addClass(name); - } - - - public void setSuperclassName( final String name ) { - superClassName = name.replace('/', '.'); - superclass_name_index = cp.addClass(name); - } - - - public Method[] getMethods() { - return methodList.toArray(new Method[methodList.size()]); + public int getClassNameIndex() { + return classNameIndex; } - - public void setMethods( final Method[] methods ) { - methodList.clear(); - for (final Method method : methods) { - addMethod(method); - } + public ConstantPoolGen getConstantPool() { + return cp; } - - public void setMethodAt( final Method method, final int pos ) { - methodList.set(pos, method); + public Field[] getFields() { + return fieldList.toArray(Field.EMPTY_ARRAY); } - - public Method getMethodAt( final int pos ) { - return methodList.get(pos); + public String getFileName() { + return fileName; } - public String[] getInterfaceNames() { - final int size = interfaceList.size(); - final String[] interfaces = new String[size]; - interfaceList.toArray(interfaces); - return interfaces; + return interfaceList.toArray(Const.EMPTY_STRING_ARRAY); } - public int[] getInterfaces() { final int size = interfaceList.size(); final int[] interfaces = new int[size]; - for (int i = 0; i < size; i++) { - interfaces[i] = cp.addClass(interfaceList.get(i)); - } + Arrays.setAll(interfaces, i -> cp.addClass(interfaceList.get(i))); return interfaces; } - - public Field[] getFields() { - return fieldList.toArray(new Field[fieldList.size()]); - } - - - public Attribute[] getAttributes() { - return attributeList.toArray(new Attribute[attributeList.size()]); + /** + * @return the (finally) built up Java class object. + */ + public JavaClass getJavaClass() { + final int[] interfaces = getInterfaces(); + final Field[] fields = getFields(); + final Method[] methods = getMethods(); + Attribute[] attributes = null; + if (annotationList.isEmpty()) { + attributes = getAttributes(); + } else { + // TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations' + final Attribute[] annAttributes = AnnotationEntryGen.getAnnotationAttributes(cp, getAnnotationEntries()); + attributes = new Attribute[attributeList.size() + annAttributes.length]; + attributeList.toArray(attributes); + System.arraycopy(annAttributes, 0, attributes, attributeList.size(), annAttributes.length); + } + // Must be last since the above calls may still add something to it + final ConstantPool cp = this.cp.getFinalConstantPool(); + return new JavaClass(classNameIndex, superclassNameIndex, fileName, major, minor, super.getAccessFlags(), cp, interfaces, fields, methods, + attributes); } - // J5TODO: Should we make calling unpackAnnotations() lazy and put it in here? - public AnnotationEntryGen[] getAnnotationEntries() { - return annotationList.toArray(new AnnotationEntryGen[annotationList.size()]); + /** + * @return major version number of class file + */ + public int getMajor() { + return major; } - - public ConstantPoolGen getConstantPool() { - return cp; + public Method getMethodAt(final int pos) { + return methodList.get(pos); } - - public void setConstantPool( final ConstantPoolGen constant_pool ) { - cp = constant_pool; + public Method[] getMethods() { + return methodList.toArray(Method.EMPTY_ARRAY); } - - public void setClassNameIndex( final int class_name_index ) { - this.classNameIndex = class_name_index; - className = cp.getConstantPool().getConstantString(class_name_index, - Const.CONSTANT_Class).replace('/', '.'); + /** + * @return minor version number of class file + */ + public int getMinor() { + return minor; } - - public void setSuperclassNameIndex( final int superclass_name_index ) { - this.superclass_name_index = superclass_name_index; - superClassName = cp.getConstantPool().getConstantString(superclass_name_index, - Const.CONSTANT_Class).replace('/', '.'); + public String getSuperclassName() { + return superClassName; } - public int getSuperclassNameIndex() { - return superclass_name_index; + return superclassNameIndex; } - - public int getClassNameIndex() { - return classNameIndex; + /** + * Return value as defined by given BCELComparator strategy. By default return the hashcode of the class name. + * + * @see Object#hashCode() + */ + @Override + public int hashCode() { + return bcelComparator.hashCode(this); } - private List observers; + /** + * Remove an attribute from this class. + * + * @param a attribute to remove + */ + public void removeAttribute(final Attribute a) { + attributeList.remove(a); + } + /** + * Remove a field to this class. + * + * @param f field to remove + */ + public void removeField(final Field f) { + fieldList.remove(f); + } - /** Add observer for this object. + /** + * Remove an interface from this class. + * + * @param name interface to remove (fully qualified name) */ - public void addObserver( final ClassObserver o ) { - if (observers == null) { - observers = new ArrayList<>(); - } - observers.add(o); + public void removeInterface(final String name) { + interfaceList.remove(name); } + /** + * Remove a method from this class. + * + * @param m method to remove + */ + public void removeMethod(final Method m) { + methodList.remove(m); + } - /** Remove observer for this object. + /** + * Remove observer for this object. */ - public void removeObserver( final ClassObserver o ) { + public void removeObserver(final ClassObserver o) { if (observers != null) { observers.remove(o); } } + /** + * Replace given field with new one. If the old one does not exist add the new_ field to the class anyway. + */ + public void replaceField(final Field old, final Field newField) { + if (newField == null) { + throw new ClassGenException("Replacement method must not be null"); + } + final int i = fieldList.indexOf(old); + if (i < 0) { + fieldList.add(newField); + } else { + fieldList.set(i, newField); + } + } - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. + /** + * Replace given method with new one. If the old one does not exist add the newMethod method to the class anyway. */ - public void update() { - if (observers != null) { - for (final ClassObserver observer : observers) { - observer.notify(this); - } + public void replaceMethod(final Method old, final Method newMethod) { + if (newMethod == null) { + throw new ClassGenException("Replacement method must not be null"); + } + final int i = methodList.indexOf(old); + if (i < 0) { + methodList.add(newMethod); + } else { + methodList.set(i, newMethod); } } + public void setClassName(final String name) { + className = Utility.pathToPackage(name); + classNameIndex = cp.addClass(name); + } - @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - throw new Error("Clone Not Supported"); // never happens - } + public void setClassNameIndex(final int classNameIndex) { + this.classNameIndex = classNameIndex; + this.className = Utility.pathToPackage(cp.getConstantPool().getConstantString(classNameIndex, Const.CONSTANT_Class)); } + public void setConstantPool(final ConstantPoolGen constantPool) { + cp = constantPool; + } /** - * @return Comparison strategy object + * Set major version number of class file, default value is 45 (JDK 1.1) + * + * @param major major version number */ - public static BCELComparator getComparator() { - return bcelComparator; + public void setMajor(final int major) { // TODO could be package-protected - only called by test code + this.major = major; } + public void setMethodAt(final Method method, final int pos) { + methodList.set(pos, method); + } + + public void setMethods(final Method[] methods) { + methodList.clear(); + Collections.addAll(methodList, methods); + } /** - * @param comparator Comparison strategy object + * Set minor version number of class file, default value is 3 (JDK 1.1) + * + * @param minor minor version number */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; + public void setMinor(final int minor) { // TODO could be package-protected - only called by test code + this.minor = minor; } + public void setSuperclassName(final String name) { + superClassName = Utility.pathToPackage(name); + superclassNameIndex = cp.addClass(name); + } + + public void setSuperclassNameIndex(final int superclassNameIndex) { + this.superclassNameIndex = superclassNameIndex; + superClassName = Utility.pathToPackage(cp.getConstantPool().getConstantString(superclassNameIndex, Const.CONSTANT_Class)); + } /** - * Return value as defined by given BCELComparator strategy. - * By default two ClassGen objects are said to be equal when - * their class names are equal. - * - * @see java.lang.Object#equals(java.lang.Object) + * Look for attributes representing annotations and unpack them. */ - @Override - public boolean equals( final Object obj ) { - return bcelComparator.equals(this, obj); + private AnnotationEntryGen[] unpackAnnotations(final Attribute[] attrs) { + final List annotationGenObjs = new ArrayList<>(); + for (final Attribute attr : attrs) { + if (attr instanceof RuntimeVisibleAnnotations) { + final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr; + rva.forEach(a -> annotationGenObjs.add(new AnnotationEntryGen(a, getConstantPool(), false))); + } else if (attr instanceof RuntimeInvisibleAnnotations) { + final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr; + ria.forEach(a -> annotationGenObjs.add(new AnnotationEntryGen(a, getConstantPool(), false))); + } + } + return annotationGenObjs.toArray(AnnotationEntryGen.EMPTY_ARRAY); } - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the class name. - * - * @see java.lang.Object#hashCode() + * Call notify() method on all observers. This method is not called automatically whenever the state has changed, but + * has to be called by the user after they have finished editing the object. */ - @Override - public int hashCode() { - return bcelComparator.hashCode(this); + public void update() { + if (observers != null) { + for (final ClassObserver observer : observers) { + observer.notify(this); + } + } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ClassObserver.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,11 +22,10 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Implement this interface if you're interested in changes to a ClassGen object - * and register yourself with addObserver(). - * + * Implement this interface if you're interested in changes to a ClassGen object and register yourself with + * addObserver(). */ public interface ClassObserver { - void notify( ClassGen clazz ); + void notify(ClassGen clazz); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,167 +23,158 @@ import com.sun.org.apache.bcel.internal.classfile.CodeException; /** - * This class represents an exception handler, i.e., specifies the region where - * a handler is active and an instruction where the actual handling is done. - * pool as parameters. Opposed to the JVM specification the end of the handled - * region is set to be inclusive, i.e. all instructions between start and end - * are protected including the start and end instructions (handles) themselves. - * The end of the region is automatically mapped to be exclusive when calling + * This class represents an exception handler, i.e., specifies the region where a handler is active and an instruction + * where the actual handling is done. pool as parameters. Opposed to the JVM specification the end of the handled region + * is set to be inclusive, i.e. all instructions between start and end are protected including the start and end + * instructions (handles) themselves. The end of the region is automatically mapped to be exclusive when calling * getCodeException(), i.e., there is no difference semantically. * - * @see MethodGen - * @see CodeException - * @see InstructionHandle + * @see MethodGen + * @see CodeException + * @see InstructionHandle */ public final class CodeExceptionGen implements InstructionTargeter, Cloneable { + static final CodeExceptionGen[] EMPTY_ARRAY = {}; + private InstructionHandle startPc; private InstructionHandle endPc; private InstructionHandle handlerPc; private ObjectType catchType; - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. + * Add an exception handler, i.e., specify region where a handler is active and an instruction where the actual handling + * is done. * * @param startPc Start of handled region (inclusive) * @param endPc End of handled region (inclusive) * @param handlerPc Where handling is done * @param catchType which exception is handled, null for ANY */ - public CodeExceptionGen(final InstructionHandle startPc, final InstructionHandle endPc, - final InstructionHandle handlerPc, final ObjectType catchType) { + public CodeExceptionGen(final InstructionHandle startPc, final InstructionHandle endPc, final InstructionHandle handlerPc, final ObjectType catchType) { setStartPC(startPc); setEndPC(endPc); setHandlerPC(handlerPc); this.catchType = catchType; } + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } /** - * Get CodeException object.
    - * - * This relies on that the instruction list has already been dumped - * to byte code or or that the `setPositions' methods has been - * called for the instruction list. - * - * @param cp constant pool + * @return true, if ih is target of this handler */ - public CodeException getCodeException( final ConstantPoolGen cp ) { - return new CodeException(startPc.getPosition(), endPc.getPosition() - + endPc.getInstruction().getLength(), handlerPc.getPosition(), - (catchType == null) ? 0 : cp.addClass(catchType)); + @Override + public boolean containsTarget(final InstructionHandle ih) { + return startPc == ih || endPc == ih || handlerPc == ih; } - - /* Set start of handler - * @param startPc Start of handled region (inclusive) - */ - public void setStartPC( final InstructionHandle start_pc ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.startPc, start_pc, this); - this.startPc = start_pc; + /** Gets the type of the Exception to catch, 'null' for ANY. */ + public ObjectType getCatchType() { + return catchType; } - - /* Set end of handler - * @param endPc End of handled region (inclusive) + /** + * Get CodeException object.
    + * + * This relies on that the instruction list has already been dumped to byte code or that the 'setPositions' methods + * has been called for the instruction list. + * + * @param cp constant pool */ - public void setEndPC( final InstructionHandle end_pc ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.endPc, end_pc, this); - this.endPc = end_pc; + public CodeException getCodeException(final ConstantPoolGen cp) { + return new CodeException(startPc.getPosition(), endPc.getPosition() + endPc.getInstruction().getLength(), handlerPc.getPosition(), + catchType == null ? 0 : cp.addClass(catchType)); } - - /* Set handler code - * @param handlerPc Start of handler + /** + * @return end of handled region (inclusive) */ - public void setHandlerPC( final InstructionHandle handler_pc ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.handlerPc, handler_pc, this); - this.handlerPc = handler_pc; + public InstructionHandle getEndPC() { + return endPc; } - /** - * @param old_ih old target, either start or end - * @param new_ih new target + * @return start of handler */ - @Override - public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { - boolean targeted = false; - if (startPc == old_ih) { - targeted = true; - setStartPC(new_ih); - } - if (endPc == old_ih) { - targeted = true; - setEndPC(new_ih); - } - if (handlerPc == old_ih) { - targeted = true; - setHandlerPC(new_ih); - } - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih + ", but {" + startPc + ", " - + endPc + ", " + handlerPc + "}"); - } + public InstructionHandle getHandlerPC() { + return handlerPc; } - /** - * @return true, if ih is target of this handler + * @return start of handled region (inclusive) */ - @Override - public boolean containsTarget( final InstructionHandle ih ) { - return (startPc == ih) || (endPc == ih) || (handlerPc == ih); + public InstructionHandle getStartPC() { + return startPc; } - /** Sets the type of the Exception to catch. Set 'null' for ANY. */ - public void setCatchType( final ObjectType catchType ) { + public void setCatchType(final ObjectType catchType) { this.catchType = catchType; } - - /** Gets the type of the Exception to catch, 'null' for ANY. */ - public ObjectType getCatchType() { - return catchType; - } - - - /** @return start of handled region (inclusive) + /* + * Set end of handler + * + * @param endPc End of handled region (inclusive) */ - public InstructionHandle getStartPC() { - return startPc; + public void setEndPC(final InstructionHandle endPc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.endPc, endPc, this); + this.endPc = endPc; } - - /** @return end of handled region (inclusive) + /* + * Set handler code + * + * @param handlerPc Start of handler */ - public InstructionHandle getEndPC() { - return endPc; + public void setHandlerPC(final InstructionHandle handlerPc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.handlerPc, handlerPc, this); + this.handlerPc = handlerPc; } - - /** @return start of handler + /* + * Set start of handler + * + * @param startPc Start of handled region (inclusive) */ - public InstructionHandle getHandlerPC() { - return handlerPc; + public void setStartPC(final InstructionHandle startPc) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.startPc, startPc, this); + this.startPc = startPc; } - @Override public String toString() { return "CodeExceptionGen(" + startPc + ", " + endPc + ", " + handlerPc + ")"; } - + /** + * @param oldIh old target, either start or end + * @param newIh new target + */ @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - throw new Error("Clone Not Supported"); // never happens + public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) { + boolean targeted = false; + if (startPc == oldIh) { + targeted = true; + setStartPC(newIh); + } + if (endPc == oldIh) { + targeted = true; + setEndPC(newIh); + } + if (handlerPc == oldIh) { + targeted = true; + setHandlerPC(newIh); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + oldIh + ", but {" + startPc + ", " + endPc + ", " + handlerPc + "}"); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CompoundInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,15 +22,12 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Wrapper class for `compound' operations, virtual instructions that - * don't exist as byte code, but give a useful meaning. For example, - * the (virtual) PUSH instruction takes an arbitray argument and produces the - * appropiate code at dump time (ICONST, LDC, BIPUSH, ...). Also you can use the - * SWITCH instruction as a useful template for either LOOKUPSWITCH or - * TABLESWITCH. + * Wrapper class for 'compound' operations, virtual instructions that don't exist as byte code, but give a useful + * meaning. For example, the (virtual) PUSH instruction takes an arbitrary argument and produces the appropriate code at + * dump time (ICONST, LDC, BIPUSH, ...). Also you can use the SWITCH instruction as a useful template for either + * LOOKUPSWITCH or TABLESWITCH. * - * The interface provides the possibilty for the user to write - * `templates' or `macros' for such reuseable code patterns. + * The interface provides the possibility for the user to write 'templates' or 'macros' for such reusable code patterns. * * @see PUSH * @see SWITCH diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPoolGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -19,6 +19,7 @@ */ package com.sun.org.apache.bcel.internal.generic; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -27,6 +28,7 @@ import com.sun.org.apache.bcel.internal.classfile.ConstantCP; import com.sun.org.apache.bcel.internal.classfile.ConstantClass; import com.sun.org.apache.bcel.internal.classfile.ConstantDouble; +import com.sun.org.apache.bcel.internal.classfile.ConstantDynamic; import com.sun.org.apache.bcel.internal.classfile.ConstantFieldref; import com.sun.org.apache.bcel.internal.classfile.ConstantFloat; import com.sun.org.apache.bcel.internal.classfile.ConstantInteger; @@ -38,45 +40,68 @@ import com.sun.org.apache.bcel.internal.classfile.ConstantPool; import com.sun.org.apache.bcel.internal.classfile.ConstantString; import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** - * This class is used to build up a constant pool. The user adds - * constants via `addXXX' methods, `addString', `addClass', - * etc.. These methods return an index into the constant - * pool. Finally, `getFinalConstantPool()' returns the constant pool - * built up. Intermediate versions of the constant pool can be - * obtained with `getConstantPool()'. A constant pool has capacity for - * Constants.MAX_SHORT entries. Note that the first (0) is used by the - * JVM and that Double and Long constants need two slots. + * This class is used to build up a constant pool. The user adds constants via 'addXXX' methods, 'addString', + * 'addClass', etc.. These methods return an index into the constant pool. Finally, 'getFinalConstantPool()' returns the + * constant pool built up. Intermediate versions of the constant pool can be obtained with 'getConstantPool()'. A + * constant pool has capacity for Constants.MAX_SHORT entries. Note that the first (0) is used by the JVM and that + * Double and Long constants need two slots. * * @see Constant - * @LastModified: June 2022 + * @LastModified: Feb 2023 */ public class ConstantPoolGen { - public static final int CONSTANT_POOL_SIZE = 65535; + private static final int DEFAULT_BUFFER_SIZE = 256; - private int size; - private Constant[] constants; - private int index = 1; // First entry (0) used by JVM private static final String METHODREF_DELIM = ":"; + private static final String IMETHODREF_DELIM = "#"; + private static final String FIELDREF_DELIM = "&"; + private static final String NAT_DELIM = "%"; // Name and Type - private static class Index { + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int size; + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected Constant[] constants; - final int index; + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getSize() + */ + @Deprecated + protected int index = 1; // First entry (0) used by JVM + private final Map stringTable = new HashMap<>(); - Index(final int i) { - index = i; - } - } + private final Map classTable = new HashMap<>(); + + private final Map utf8Table = new HashMap<>(); + private final Map natTable = new HashMap<>(); + + private final Map cpTable = new HashMap<>(); + + /** + * Constructs a new empty constant pool. + */ + public ConstantPoolGen() { + size = DEFAULT_BUFFER_SIZE; + constants = new Constant[size]; + } /** - * Initialize with given array of constants. + * Constructs a new instance with the given array of constants. * * @param cs array of given constants, new ones will be appended */ @@ -88,15 +113,15 @@ * This is however, not used by XSLT (or the java.xml implementation), * and only happens when BCELifier is called (see BCELifier). */ - if (cs.length > CONSTANT_POOL_SIZE) { - throw new RuntimeException("The number of constants " + cs.length + if (cs.length > Const.MAX_CP_ENTRIES) { + throw new IllegalStateException("The number of constants " + cs.length + " is over the size limit of the constant pool: " - + CONSTANT_POOL_SIZE); + + Const.MAX_CP_ENTRIES); } final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE); - size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), CONSTANT_POOL_SIZE); + size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), Const.MAX_CP_ENTRIES); constants = new Constant[size]; System.arraycopy(cs, 0, constants, 0, cs.length); @@ -104,7 +129,6 @@ index = cs.length; } - for (int i = 1; i < index; i++) { final Constant c = constants[i]; if (c instanceof ConstantString) { @@ -112,56 +136,57 @@ final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; final String key = u8.getBytes(); if (!stringTable.containsKey(key)) { - stringTable.put(key, new Index(i)); + stringTable.put(key, Integer.valueOf(i)); } } else if (c instanceof ConstantClass) { final ConstantClass s = (ConstantClass) c; final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; final String key = u8.getBytes(); if (!classTable.containsKey(key)) { - classTable.put(key, new Index(i)); + classTable.put(key, Integer.valueOf(i)); } } else if (c instanceof ConstantNameAndType) { final ConstantNameAndType n = (ConstantNameAndType) c; - final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; - final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; + final ConstantUtf8 u8NameIdx = (ConstantUtf8) constants[n.getNameIndex()]; + final ConstantUtf8 u8SigIdx = (ConstantUtf8) constants[n.getSignatureIndex()]; - sb.append(u8.getBytes()); + sb.append(u8NameIdx.getBytes()); sb.append(NAT_DELIM); - sb.append(u8_2.getBytes()); + sb.append(u8SigIdx.getBytes()); final String key = sb.toString(); sb.delete(0, sb.length()); if (!natTable.containsKey(key)) { - natTable.put(key, new Index(i)); + natTable.put(key, Integer.valueOf(i)); } } else if (c instanceof ConstantUtf8) { final ConstantUtf8 u = (ConstantUtf8) c; final String key = u.getBytes(); if (!utf8Table.containsKey(key)) { - utf8Table.put(key, new Index(i)); + utf8Table.put(key, Integer.valueOf(i)); } } else if (c instanceof ConstantCP) { final ConstantCP m = (ConstantCP) c; - String class_name; + String className; ConstantUtf8 u8; if (c instanceof ConstantInvokeDynamic) { - class_name = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); - // since name can't begin with digit, can use - // METHODREF_DELIM with out fear of duplicates. + className = Integer.toString(((ConstantInvokeDynamic) m).getBootstrapMethodAttrIndex()); + } else if (c instanceof ConstantDynamic) { + className = Integer.toString(((ConstantDynamic) m).getBootstrapMethodAttrIndex()); } else { - final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; - class_name = u8.getBytes().replace('/', '.'); + className = Utility.pathToPackage(u8.getBytes()); } final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; u8 = (ConstantUtf8) constants[n.getNameIndex()]; - final String method_name = u8.getBytes(); + final String methodName = u8.getBytes(); u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; final String signature = u8.getBytes(); + // Since name cannot begin with digit, we can use METHODREF_DELIM without fear of duplicates String delim = METHODREF_DELIM; if (c instanceof ConstantInterfaceMethodref) { delim = IMETHODREF_DELIM; @@ -169,245 +194,205 @@ delim = FIELDREF_DELIM; } - sb.append(class_name); + sb.append(className); sb.append(delim); - sb.append(method_name); + sb.append(methodName); sb.append(delim); sb.append(signature); final String key = sb.toString(); sb.delete(0, sb.length()); if (!cpTable.containsKey(key)) { - cpTable.put(key, new Index(i)); + cpTable.put(key, Integer.valueOf(i)); } - } else if (c == null) { // entries may be null - // nothing to do - } else if (c instanceof ConstantInteger) { - // nothing to do - } else if (c instanceof ConstantLong) { - // nothing to do - } else if (c instanceof ConstantFloat) { - // nothing to do - } else if (c instanceof ConstantDouble) { - // nothing to do - } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) { - // TODO should this be handled somehow? - } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) { - // TODO should this be handled somehow? - } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantModule) { - // TODO should this be handled somehow? - } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantPackage) { - // TODO should this be handled somehow? - } else { - assert false : "Unexpected constant type: " + c.getClass().getName(); } +// else if (c == null) { // entries may be null +// // nothing to do +// } else if (c instanceof ConstantInteger) { +// // nothing to do +// } else if (c instanceof ConstantLong) { +// // nothing to do +// } else if (c instanceof ConstantFloat) { +// // nothing to do +// } else if (c instanceof ConstantDouble) { +// // nothing to do +// } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodType) { +// // TODO should this be handled somehow? +// } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantMethodHandle) { +// // TODO should this be handled somehow? +// } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantModule) { +// // TODO should this be handled somehow? +// } else if (c instanceof com.sun.org.apache.bcel.internal.classfile.ConstantPackage) { +// // TODO should this be handled somehow? +// } else { +// // Not helpful, should throw an exception. +// assert false : "Unexpected constant type: " + c.getClass().getName(); +// } } } - /** - * Initialize with given constant pool. + * Constructs a new instance with the given constant pool. + * + * @param cp the constant pool. */ public ConstantPoolGen(final ConstantPool cp) { this(cp.getConstantPool()); } - - /** - * Create empty constant pool. - */ - public ConstantPoolGen() { - size = DEFAULT_BUFFER_SIZE; - constants = new Constant[size]; - } - - - /** Resize internal array of constants. - */ - protected void adjustSize() { - // 3 extra spaces are needed as some entries may take 3 slots - if (index + 3 >= CONSTANT_POOL_SIZE) { - throw new RuntimeException("The number of constants " + (index + 3) - + " is over the size limit of the constant pool: " - + CONSTANT_POOL_SIZE); - } - - if (index + 3 >= size) { - final Constant[] cs = constants; - size *= 2; - // the constant array shall not exceed the size of the constant pool - size = Math.min(size, CONSTANT_POOL_SIZE); - constants = new Constant[size]; - System.arraycopy(cs, 0, constants, 0, index); - } - } - - private final Map stringTable = new HashMap<>(); - - /** - * Look for ConstantString in ConstantPool containing String `str'. + * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY instruction, e.g. to the + * ConstantPool. * - * @param str String to search for - * @return index on success, -1 otherwise + * @param type type of array class + * @return index of entry */ - public int lookupString( final String str ) { - final Index index = stringTable.get(str); - return (index != null) ? index.index : -1; + public int addArrayClass(final ArrayType type) { + return addClass_(type.getSignature()); } - /** - * Add a new String constant to the ConstantPool, if it is not already in there. + * Add a new Class reference to the ConstantPool for a given type. * - * @param str String to add + * @param type Class to add * @return index of entry */ - public int addString( final String str ) { - int ret; - if ((ret = lookupString(str)) != -1) { - return ret; // Already in CP - } - final int utf8 = addUtf8(str); - adjustSize(); - final ConstantString s = new ConstantString(utf8); - ret = index; - constants[index++] = s; - if (!stringTable.containsKey(str)) { - stringTable.put(str, new Index(ret)); - } - return ret; + public int addClass(final ObjectType type) { + return addClass(type.getClassName()); } - private final Map classTable = new HashMap<>(); - - /** - * Look for ConstantClass in ConstantPool named `str'. + * Add a new Class reference to the ConstantPool, if it is not already in there. * - * @param str String to search for - * @return index on success, -1 otherwise + * @param str Class to add + * @return index of entry */ - public int lookupClass( final String str ) { - final Index index = classTable.get(str.replace('.', '/')); - return (index != null) ? index.index : -1; + public int addClass(final String str) { + return addClass_(Utility.packageToPath(str)); } - - private int addClass_( final String clazz ) { - int ret; - if ((ret = lookupClass(clazz)) != -1) { - return ret; // Already in CP + private int addClass_(final String clazz) { + final int cpRet; + if ((cpRet = lookupClass(clazz)) != -1) { + return cpRet; // Already in CP } adjustSize(); final ConstantClass c = new ConstantClass(addUtf8(clazz)); - ret = index; + final int ret = index; constants[index++] = c; - if (!classTable.containsKey(clazz)) { - classTable.put(clazz, new Index(ret)); - } - return ret; - } - - - /** - * Add a new Class reference to the ConstantPool, if it is not already in there. - * - * @param str Class to add - * @return index of entry - */ - public int addClass( final String str ) { - return addClass_(str.replace('.', '/')); - } - - - /** - * Add a new Class reference to the ConstantPool for a given type. - * - * @param type Class to add - * @return index of entry - */ - public int addClass( final ObjectType type ) { - return addClass(type.getClassName()); + return computeIfAbsent(classTable, clazz, ret); } - /** - * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY - * instruction, e.g. to the ConstantPool. + * Adds a constant from another ConstantPool and returns the new index. * - * @param type type of array class + * @param constant The constant to add. + * @param cpGen Source pool. * @return index of entry */ - public int addArrayClass( final ArrayType type ) { - return addClass_(type.getSignature()); - } - - - /** - * Look for ConstantInteger in ConstantPool. - * - * @param n integer number to look for - * @return index on success, -1 otherwise - */ - public int lookupInteger( final int n ) { - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantInteger) { - final ConstantInteger c = (ConstantInteger) constants[i]; - if (c.getBytes() == n) { - return i; - } + public int addConstant(final Constant constant, final ConstantPoolGen cpGen) { + final Constant[] constants = cpGen.getConstantPool().getConstantPool(); + switch (constant.getTag()) { + case Const.CONSTANT_String: { + final ConstantString s = (ConstantString) constant; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; + return addString(u8.getBytes()); + } + case Const.CONSTANT_Class: { + final ConstantClass s = (ConstantClass) constant; + final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; + return addClass(u8.getBytes()); + } + case Const.CONSTANT_NameAndType: { + final ConstantNameAndType n = (ConstantNameAndType) constant; + final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; + return addNameAndType(u8.getBytes(), u8_2.getBytes()); + } + case Const.CONSTANT_Utf8: + return addUtf8(((ConstantUtf8) constant).getBytes()); + case Const.CONSTANT_Double: + return addDouble(((ConstantDouble) constant).getBytes()); + case Const.CONSTANT_Float: + return addFloat(((ConstantFloat) constant).getBytes()); + case Const.CONSTANT_Long: + return addLong(((ConstantLong) constant).getBytes()); + case Const.CONSTANT_Integer: + return addInteger(((ConstantInteger) constant).getBytes()); + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + case Const.CONSTANT_Fieldref: { + final ConstantCP m = (ConstantCP) constant; + final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; + ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + final String className = Utility.pathToPackage(u8.getBytes()); + u8 = (ConstantUtf8) constants[n.getNameIndex()]; + final String name = u8.getBytes(); + u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; + final String signature = u8.getBytes(); + switch (constant.getTag()) { + case Const.CONSTANT_InterfaceMethodref: + return addInterfaceMethodref(className, name, signature); + case Const.CONSTANT_Methodref: + return addMethodref(className, name, signature); + case Const.CONSTANT_Fieldref: + return addFieldref(className, name, signature); + default: // Never reached + throw new IllegalArgumentException("Unknown constant type " + constant); } } - return -1; + default: // Never reached + throw new IllegalArgumentException("Unknown constant type " + constant); + } } - /** - * Add a new Integer constant to the ConstantPool, if it is not already in there. + * Add a new double constant to the ConstantPool, if it is not already in there. * - * @param n integer number to add + * @param n Double number to add * @return index of entry */ - public int addInteger( final int n ) { + public int addDouble(final double n) { int ret; - if ((ret = lookupInteger(n)) != -1) { + if ((ret = lookupDouble(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; - constants[index++] = new ConstantInteger(n); + constants[index] = new ConstantDouble(n); + index += 2; // Wastes one entry according to spec return ret; } - /** - * Look for ConstantFloat in ConstantPool. + * Add a new Fieldref constant to the ConstantPool, if it is not already in there. * - * @param n Float number to look for - * @return index on success, -1 otherwise + * @param className class name string to add + * @param fieldName field name string to add + * @param signature signature string to add + * @return index of entry */ - public int lookupFloat( final float n ) { - final int bits = Float.floatToIntBits(n); - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantFloat) { - final ConstantFloat c = (ConstantFloat) constants[i]; - if (Float.floatToIntBits(c.getBytes()) == bits) { - return i; - } - } + public int addFieldref(final String className, final String fieldName, final String signature) { + final int cpRet; + if ((cpRet = lookupFieldref(className, fieldName, signature)) != -1) { + return cpRet; // Already in CP } - return -1; + adjustSize(); + final int classIndex = addClass(className); + final int nameAndTypeIndex = addNameAndType(fieldName, signature); + final int ret = index; + constants[index++] = new ConstantFieldref(classIndex, nameAndTypeIndex); + return computeIfAbsent(cpTable, className + FIELDREF_DELIM + fieldName + FIELDREF_DELIM + signature, ret); } - /** * Add a new Float constant to the ConstantPool, if it is not already in there. * * @param n Float number to add * @return index of entry */ - public int addFloat( final float n ) { + public int addFloat(final float n) { int ret; if ((ret = lookupFloat(n)) != -1) { return ret; // Already in CP @@ -418,68 +403,55 @@ return ret; } - private final Map utf8Table = new HashMap<>(); - - - /** - * Look for ConstantUtf8 in ConstantPool. - * - * @param n Utf8 string to look for - * @return index on success, -1 otherwise - */ - public int lookupUtf8( final String n ) { - final Index index = utf8Table.get(n); - return (index != null) ? index.index : -1; - } - - /** - * Add a new Utf8 constant to the ConstantPool, if it is not already in there. + * Add a new Integer constant to the ConstantPool, if it is not already in there. * - * @param n Utf8 string to add + * @param n integer number to add * @return index of entry */ - public int addUtf8( final String n ) { + public int addInteger(final int n) { int ret; - if ((ret = lookupUtf8(n)) != -1) { + if ((ret = lookupInteger(n)) != -1) { return ret; // Already in CP } adjustSize(); ret = index; - constants[index++] = new ConstantUtf8(n); - if (!utf8Table.containsKey(n)) { - utf8Table.put(n, new Index(ret)); - } + constants[index++] = new ConstantInteger(n); return ret; } + public int addInterfaceMethodref(final MethodGen method) { + return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); + } /** - * Look for ConstantLong in ConstantPool. + * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already in there. * - * @param n Long number to look for - * @return index on success, -1 otherwise + * @param className class name string to add + * @param methodName method name string to add + * @param signature signature string to add + * @return index of entry */ - public int lookupLong( final long n ) { - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantLong) { - final ConstantLong c = (ConstantLong) constants[i]; - if (c.getBytes() == n) { - return i; - } - } + public int addInterfaceMethodref(final String className, final String methodName, final String signature) { + final int cpRet; + if ((cpRet = lookupInterfaceMethodref(className, methodName, signature)) != -1) { + return cpRet; // Already in CP } - return -1; + adjustSize(); + final int classIndex = addClass(className); + final int nameAndTypeIndex = addNameAndType(methodName, signature); + final int ret = index; + constants[index++] = new ConstantInterfaceMethodref(classIndex, nameAndTypeIndex); + return computeIfAbsent(cpTable, className + IMETHODREF_DELIM + methodName + IMETHODREF_DELIM + signature, ret); } - /** * Add a new long constant to the ConstantPool, if it is not already in there. * * @param n Long number to add * @return index of entry */ - public int addLong( final long n ) { + public int addLong(final long n) { int ret; if ((ret = lookupLong(n)) != -1) { return ret; // Already in CP @@ -490,290 +462,317 @@ index += 2; // Wastes one entry according to spec return ret; } - + public int addMethodref(final MethodGen method) { + return addMethodref(method.getClassName(), method.getName(), method.getSignature()); + } /** - * Look for ConstantDouble in ConstantPool. + * Add a new Methodref constant to the ConstantPool, if it is not already in there. * - * @param n Double number to look for - * @return index on success, -1 otherwise + * @param className class name string to add + * @param methodName method name string to add + * @param signature method signature string to add + * @return index of entry */ - public int lookupDouble( final double n ) { - final long bits = Double.doubleToLongBits(n); - for (int i = 1; i < index; i++) { - if (constants[i] instanceof ConstantDouble) { - final ConstantDouble c = (ConstantDouble) constants[i]; - if (Double.doubleToLongBits(c.getBytes()) == bits) { - return i; - } - } + public int addMethodref(final String className, final String methodName, final String signature) { + final int cpRet; + if ((cpRet = lookupMethodref(className, methodName, signature)) != -1) { + return cpRet; // Already in CP } - return -1; + adjustSize(); + final int nameAndTypeIndex = addNameAndType(methodName, signature); + final int classIndex = addClass(className); + final int ret = index; + constants[index++] = new ConstantMethodref(classIndex, nameAndTypeIndex); + return computeIfAbsent(cpTable, className + METHODREF_DELIM + methodName + METHODREF_DELIM + signature, ret); } - /** - * Add a new double constant to the ConstantPool, if it is not already in there. + * Add a new NameAndType constant to the ConstantPool if it is not already in there. * - * @param n Double number to add + * @param name Name string to add + * @param signature signature string to add * @return index of entry */ - public int addDouble( final double n ) { + public int addNameAndType(final String name, final String signature) { int ret; - if ((ret = lookupDouble(n)) != -1) { + if ((ret = lookupNameAndType(name, signature)) != -1) { return ret; // Already in CP } adjustSize(); + final int nameIndex = addUtf8(name); + final int signatureIndex = addUtf8(signature); ret = index; - constants[index] = new ConstantDouble(n); - index += 2; // Wastes one entry according to spec - return ret; + constants[index++] = new ConstantNameAndType(nameIndex, signatureIndex); + return computeIfAbsent(natTable, name + NAT_DELIM + signature, ret); } - private final Map natTable = new HashMap<>(); - - /** - * Look for ConstantNameAndType in ConstantPool. + * Add a new String constant to the ConstantPool, if it is not already in there. * - * @param name of variable/method - * @param signature of variable/method - * @return index on success, -1 otherwise + * @param str String to add + * @return index of entry */ - public int lookupNameAndType( final String name, final String signature ) { - final Index _index = natTable.get(name + NAT_DELIM + signature); - return (_index != null) ? _index.index : -1; + public int addString(final String str) { + int ret; + if ((ret = lookupString(str)) != -1) { + return ret; // Already in CP + } + final int utf8 = addUtf8(str); + adjustSize(); + final ConstantString s = new ConstantString(utf8); + ret = index; + constants[index++] = s; + return computeIfAbsent(stringTable, str, ret); } - /** - * Add a new NameAndType constant to the ConstantPool if it is not already - * in there. + * Add a new Utf8 constant to the ConstantPool, if it is not already in there. * - * @param name Name string to add - * @param signature signature string to add + * @param n Utf8 string to add * @return index of entry */ - public int addNameAndType( final String name, final String signature ) { + public int addUtf8(final String n) { int ret; - int name_index; - int signature_index; - if ((ret = lookupNameAndType(name, signature)) != -1) { + if ((ret = lookupUtf8(n)) != -1) { return ret; // Already in CP } adjustSize(); - name_index = addUtf8(name); - signature_index = addUtf8(signature); ret = index; - constants[index++] = new ConstantNameAndType(name_index, signature_index); - final String key = name + NAT_DELIM + signature; - if (!natTable.containsKey(key)) { - natTable.put(key, new Index(ret)); + constants[index++] = new ConstantUtf8(n); + return computeIfAbsent(utf8Table, n, ret); + } + + /** + * Resize internal array of constants. + */ + protected void adjustSize() { + // 3 extra spaces are needed as some entries may take 3 slots + if (index + 3 >= Const.MAX_CP_ENTRIES) { + throw new IllegalStateException("The number of constants " + (index + 3) + + " is over the size limit of the constant pool: " + + Const.MAX_CP_ENTRIES); + } + + if (index + 3 >= size) { + final Constant[] cs = constants; + size *= 2; + // the constant array shall not exceed the size of the constant pool + size = Math.min(size, Const.MAX_CP_ENTRIES); + constants = new Constant[size]; + System.arraycopy(cs, 0, constants, 0, index); } - return ret; } - private final Map cpTable = new HashMap<>(); + private int computeIfAbsent(final Map map, final String key, final int value) { + return map.computeIfAbsent(key, k -> Integer.valueOf(value)); + } + /** + * @param i index in constant pool + * @return constant pool entry at index i + */ + public Constant getConstant(final int i) { + return constants[i]; + } /** - * Look for ConstantMethodref in ConstantPool. - * - * @param class_name Where to find method - * @param method_name Guess what - * @param signature return and argument types - * @return index on success, -1 otherwise + * @return intermediate constant pool */ - public int lookupMethodref( final String class_name, final String method_name, final String signature ) { - final Index index = cpTable.get(class_name + METHODREF_DELIM + method_name - + METHODREF_DELIM + signature); - return (index != null) ? index.index : -1; + public ConstantPool getConstantPool() { + return new ConstantPool(constants); } + /** + * @return constant pool with proper length + */ + public ConstantPool getFinalConstantPool() { + return new ConstantPool(Arrays.copyOf(constants, index)); + } - public int lookupMethodref( final MethodGen method ) { - return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); + private int getIndex(final Map map, final String key) { + return toIndex(map.get(key)); } + /** + * @return current size of constant pool + */ + public int getSize() { + return index; + } /** - * Add a new Methodref constant to the ConstantPool, if it is not already - * in there. + * Look for ConstantClass in ConstantPool named 'str'. * - * @param class_name class name string to add - * @param method_name method name string to add - * @param signature method signature string to add - * @return index of entry + * @param str String to search for + * @return index on success, -1 otherwise */ - public int addMethodref( final String class_name, final String method_name, final String signature ) { - int ret; - int class_index; - int name_and_type_index; - if ((ret = lookupMethodref(class_name, method_name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - name_and_type_index = addNameAndType(method_name, signature); - class_index = addClass(class_name); - ret = index; - constants[index++] = new ConstantMethodref(class_index, name_and_type_index); - final String key = class_name + METHODREF_DELIM + method_name + METHODREF_DELIM + signature; - if (!cpTable.containsKey(key)) { - cpTable.put(key, new Index(ret)); - } - return ret; + public int lookupClass(final String str) { + return getIndex(classTable, Utility.packageToPath(str)); } - - public int addMethodref( final MethodGen method ) { - return addMethodref(method.getClassName(), method.getName(), method.getSignature()); + /** + * Look for ConstantDouble in ConstantPool. + * + * @param n Double number to look for + * @return index on success, -1 otherwise + */ + public int lookupDouble(final double n) { + final long bits = Double.doubleToLongBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantDouble) { + final ConstantDouble c = (ConstantDouble) constants[i]; + if (Double.doubleToLongBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; } - /** - * Look for ConstantInterfaceMethodref in ConstantPool. + * Look for ConstantFieldref in ConstantPool. * - * @param class_name Where to find method - * @param method_name Guess what + * @param className Where to find method + * @param fieldName Guess what * @param signature return and argument types * @return index on success, -1 otherwise */ - public int lookupInterfaceMethodref( final String class_name, final String method_name, final String signature ) { - final Index index = cpTable.get(class_name + IMETHODREF_DELIM + method_name - + IMETHODREF_DELIM + signature); - return (index != null) ? index.index : -1; + public int lookupFieldref(final String className, final String fieldName, final String signature) { + return getIndex(cpTable, className + FIELDREF_DELIM + fieldName + FIELDREF_DELIM + signature); } - - public int lookupInterfaceMethodref( final MethodGen method ) { - return lookupInterfaceMethodref(method.getClassName(), method.getName(), method - .getSignature()); + /** + * Look for ConstantFloat in ConstantPool. + * + * @param n Float number to look for + * @return index on success, -1 otherwise + */ + public int lookupFloat(final float n) { + final int bits = Float.floatToIntBits(n); + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantFloat) { + final ConstantFloat c = (ConstantFloat) constants[i]; + if (Float.floatToIntBits(c.getBytes()) == bits) { + return i; + } + } + } + return -1; } - /** - * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already - * in there. + * Look for ConstantInteger in ConstantPool. * - * @param class_name class name string to add - * @param method_name method name string to add - * @param signature signature string to add - * @return index of entry + * @param n integer number to look for + * @return index on success, -1 otherwise */ - public int addInterfaceMethodref( final String class_name, final String method_name, final String signature ) { - int ret; - int class_index; - int name_and_type_index; - if ((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - class_index = addClass(class_name); - name_and_type_index = addNameAndType(method_name, signature); - ret = index; - constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index); - final String key = class_name + IMETHODREF_DELIM + method_name + IMETHODREF_DELIM + signature; - if (!cpTable.containsKey(key)) { - cpTable.put(key, new Index(ret)); + public int lookupInteger(final int n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantInteger) { + final ConstantInteger c = (ConstantInteger) constants[i]; + if (c.getBytes() == n) { + return i; + } + } } - return ret; + return -1; } - - public int addInterfaceMethodref( final MethodGen method ) { - return addInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); + public int lookupInterfaceMethodref(final MethodGen method) { + return lookupInterfaceMethodref(method.getClassName(), method.getName(), method.getSignature()); } - /** - * Look for ConstantFieldref in ConstantPool. + * Look for ConstantInterfaceMethodref in ConstantPool. * - * @param class_name Where to find method - * @param field_name Guess what + * @param className Where to find method + * @param methodName Guess what * @param signature return and argument types * @return index on success, -1 otherwise */ - public int lookupFieldref( final String class_name, final String field_name, final String signature ) { - final Index index = cpTable.get(class_name + FIELDREF_DELIM + field_name - + FIELDREF_DELIM + signature); - return (index != null) ? index.index : -1; + public int lookupInterfaceMethodref(final String className, final String methodName, final String signature) { + return getIndex(cpTable, className + IMETHODREF_DELIM + methodName + IMETHODREF_DELIM + signature); } - /** - * Add a new Fieldref constant to the ConstantPool, if it is not already - * in there. + * Look for ConstantLong in ConstantPool. * - * @param class_name class name string to add - * @param field_name field name string to add - * @param signature signature string to add - * @return index of entry + * @param n Long number to look for + * @return index on success, -1 otherwise */ - public int addFieldref( final String class_name, final String field_name, final String signature ) { - int ret; - int class_index; - int name_and_type_index; - if ((ret = lookupFieldref(class_name, field_name, signature)) != -1) { - return ret; // Already in CP - } - adjustSize(); - class_index = addClass(class_name); - name_and_type_index = addNameAndType(field_name, signature); - ret = index; - constants[index++] = new ConstantFieldref(class_index, name_and_type_index); - final String key = class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature; - if (!cpTable.containsKey(key)) { - cpTable.put(key, new Index(ret)); + public int lookupLong(final long n) { + for (int i = 1; i < index; i++) { + if (constants[i] instanceof ConstantLong) { + final ConstantLong c = (ConstantLong) constants[i]; + if (c.getBytes() == n) { + return i; + } + } } - return ret; + return -1; } + public int lookupMethodref(final MethodGen method) { + return lookupMethodref(method.getClassName(), method.getName(), method.getSignature()); + } /** - * @param i index in constant pool - * @return constant pool entry at index i + * Look for ConstantMethodref in ConstantPool. + * + * @param className Where to find method + * @param methodName Guess what + * @param signature return and argument types + * @return index on success, -1 otherwise */ - public Constant getConstant( final int i ) { - return constants[i]; + public int lookupMethodref(final String className, final String methodName, final String signature) { + return getIndex(cpTable, className + METHODREF_DELIM + methodName + METHODREF_DELIM + signature); } - /** - * Use with care! + * Look for ConstantNameAndType in ConstantPool. * - * @param i index in constant pool - * @param c new constant pool entry at index i + * @param name of variable/method + * @param signature of variable/method + * @return index on success, -1 otherwise */ - public void setConstant( final int i, final Constant c ) { - constants[i] = c; + public int lookupNameAndType(final String name, final String signature) { + return getIndex(natTable, name + NAT_DELIM + signature); } - /** - * @return intermediate constant pool + * Look for ConstantString in ConstantPool containing String 'str'. + * + * @param str String to search for + * @return index on success, -1 otherwise */ - public ConstantPool getConstantPool() { - return new ConstantPool(constants); + public int lookupString(final String str) { + return getIndex(stringTable, str); } - /** - * @return current size of constant pool + * Look for ConstantUtf8 in ConstantPool. + * + * @param n Utf8 string to look for + * @return index on success, -1 otherwise */ - public int getSize() { - return index; + public int lookupUtf8(final String n) { + return getIndex(utf8Table, n); } - /** - * @return constant pool with proper length + * Use with care! + * + * @param i index in constant pool + * @param c new constant pool entry at index i */ - public ConstantPool getFinalConstantPool() { - final Constant[] cs = new Constant[index]; - System.arraycopy(constants, 0, cs, 0, index); - return new ConstantPool(cs); + public void setConstant(final int i, final Constant c) { + constants[i] = c; } + private int toIndex(final Integer index) { + return index != null ? index.intValue() : -1; + } /** * @return String representation. @@ -786,64 +785,4 @@ } return buf.toString(); } - - - /** Import constant from another ConstantPool and return new index. - */ - public int addConstant( final Constant c, final ConstantPoolGen cp ) { - final Constant[] constants = cp.getConstantPool().getConstantPool(); - switch (c.getTag()) { - case Const.CONSTANT_String: { - final ConstantString s = (ConstantString) c; - final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()]; - return addString(u8.getBytes()); - } - case Const.CONSTANT_Class: { - final ConstantClass s = (ConstantClass) c; - final ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()]; - return addClass(u8.getBytes()); - } - case Const.CONSTANT_NameAndType: { - final ConstantNameAndType n = (ConstantNameAndType) c; - final ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()]; - final ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()]; - return addNameAndType(u8.getBytes(), u8_2.getBytes()); - } - case Const.CONSTANT_Utf8: - return addUtf8(((ConstantUtf8) c).getBytes()); - case Const.CONSTANT_Double: - return addDouble(((ConstantDouble) c).getBytes()); - case Const.CONSTANT_Float: - return addFloat(((ConstantFloat) c).getBytes()); - case Const.CONSTANT_Long: - return addLong(((ConstantLong) c).getBytes()); - case Const.CONSTANT_Integer: - return addInteger(((ConstantInteger) c).getBytes()); - case Const.CONSTANT_InterfaceMethodref: - case Const.CONSTANT_Methodref: - case Const.CONSTANT_Fieldref: { - final ConstantCP m = (ConstantCP) c; - final ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; - final ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; - final String class_name = u8.getBytes().replace('/', '.'); - u8 = (ConstantUtf8) constants[n.getNameIndex()]; - final String name = u8.getBytes(); - u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; - final String signature = u8.getBytes(); - switch (c.getTag()) { - case Const.CONSTANT_InterfaceMethodref: - return addInterfaceMethodref(class_name, name, signature); - case Const.CONSTANT_Methodref: - return addMethodref(class_name, name, signature); - case Const.CONSTANT_Fieldref: - return addFieldref(class_name, name, signature); - default: // Never reached - throw new IllegalArgumentException("Unknown constant type " + c); - } - } - default: // Never reached - throw new IllegalArgumentException("Unknown constant type " + c); - } - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConstantPushInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,10 +22,9 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denotes a push instruction that produces a literal on the stack - * such as SIPUSH, BIPUSH, ICONST, etc. + * Denotes a push instruction that produces a literal on the stack such as SIPUSH, BIPUSH, ICONST, etc. + * * - * @see ICONST * @see SIPUSH */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ConversionInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,19 +25,15 @@ /** * Super class for the x2y family of instructions. - * */ -public abstract class ConversionInstruction extends Instruction implements TypedInstruction, - StackProducer, StackConsumer { +public abstract class ConversionInstruction extends Instruction implements TypedInstruction, StackProducer, StackConsumer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ConversionInstruction() { } - /** * @param opcode opcode of instruction */ @@ -45,37 +41,37 @@ super(opcode, (short) 1); } - - /** @return type associated with the instruction + /** + * @return type associated with the instruction */ @Override - public Type getType( final ConstantPoolGen cp ) { - final short _opcode = super.getOpcode(); - switch (_opcode) { - case Const.D2I: - case Const.F2I: - case Const.L2I: - return Type.INT; - case Const.D2F: - case Const.I2F: - case Const.L2F: - return Type.FLOAT; - case Const.D2L: - case Const.F2L: - case Const.I2L: - return Type.LONG; - case Const.F2D: - case Const.I2D: - case Const.L2D: - return Type.DOUBLE; - case Const.I2B: - return Type.BYTE; - case Const.I2C: - return Type.CHAR; - case Const.I2S: - return Type.SHORT; - default: // Never reached - throw new ClassGenException("Unknown type " + _opcode); + public Type getType(final ConstantPoolGen cp) { + final short opcode = super.getOpcode(); + switch (opcode) { + case Const.D2I: + case Const.F2I: + case Const.L2I: + return Type.INT; + case Const.D2F: + case Const.I2F: + case Const.L2F: + return Type.FLOAT; + case Const.D2L: + case Const.F2L: + case Const.I2L: + return Type.LONG; + case Const.F2D: + case Const.I2D: + case Const.L2D: + return Type.DOUBLE; + case Const.I2B: + return Type.BYTE; + case Const.I2C: + return Type.CHAR; + case Const.I2S: + return Type.SHORT; + default: // Never reached + throw new ClassGenException("Unknown type " + opcode); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/CPInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,11 +25,11 @@ import com.sun.org.apache.bcel.internal.classfile.Constant; import com.sun.org.apache.bcel.internal.classfile.ConstantClass; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.Utility; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** - * Abstract super class for instructions that use an index into the - * constant pool such as LDC, INVOKEVIRTUAL, etc. + * Abstract super class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc. * * @see ConstantPoolGen * @see LDC @@ -37,20 +37,20 @@ * * @LastModified: Jan 2020 */ -public abstract class CPInstruction extends Instruction implements TypedInstruction, - IndexedInstruction { - - private int index; // index to constant pool +public abstract class CPInstruction extends Instruction implements TypedInstruction, IndexedInstruction { + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int index; // index to constant pool /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ CPInstruction() { } - /** * @param index to constant pool */ @@ -59,90 +59,87 @@ setIndex(index); } - /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { out.writeByte(super.getOpcode()); out.writeShort(index); } - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< constant pool index>">" - * - * @param verbose long/short format switch - * @return mnemonic for instruction + * @return index in constant pool referred by this instruction. */ @Override - public String toString( final boolean verbose ) { - return super.toString(verbose) + " " + index; + public final int getIndex() { + return index; } - /** - * @return mnemonic for instruction with symbolic references resolved + * @return type related with this instruction. */ @Override - public String toString( final ConstantPool cp ) { - final Constant c = cp.getConstant(index); - String str = cp.constantToString(c); - if (c instanceof ConstantClass) { - str = str.replace('.', '/'); + public Type getType(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Const.CONSTANT_Class); + if (!name.startsWith("[")) { + name = "L" + name + ";"; } - return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + str; + return Type.getType(name); } - /** * Read needed data (i.e., index) from file. + * * @param bytes input stream * @param wide wide prefix? */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { setIndex(bytes.readUnsignedShort()); super.setLength(3); } - - /** - * @return index in constant pool referred by this instruction. - */ - @Override - public final int getIndex() { - return index; - } - - /** * Set the index to constant pool. - * @param index in constant pool. + * + * @param index in constant pool. */ @Override - public void setIndex( final int index ) { // TODO could be package-protected? + public void setIndex(final int index) { // TODO could be package-protected? if (index < 0) { throw new ClassGenException("Negative index value: " + index); } this.index = index; } + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of instruction>")" "<"< constant pool + * index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + @Override + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + index; + } - /** @return type related with this instruction. + /** + * @return mnemonic for instruction with symbolic references resolved */ @Override - public Type getType( final ConstantPoolGen cpg ) { - final ConstantPool cp = cpg.getConstantPool(); - String name = cp.getConstantString(index, com.sun.org.apache.bcel.internal.Const.CONSTANT_Class); - if (!name.startsWith("[")) { - name = "L" + name + ";"; + public String toString(final ConstantPool cp) { + final Constant c = cp.getConstant(index); + String str = cp.constantToString(c); + if (c instanceof ConstantClass) { + str = Utility.packageToPath(str); } - return Type.getType(name); + return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + str; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2F.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * D2F - Convert double to float - *
    Stack: ..., value.word1, value.word2 -> ..., result
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result
    + * 
    */ public class D2F extends ConversionInstruction { - /** Convert double to float + /** + * Convert double to float */ public D2F() { super(com.sun.org.apache.bcel.internal.Const.D2F); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2I.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * D2I - Convert double to int - *
    Stack: ..., value.word1, value.word2 -> ..., result
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result
    + * 
    */ public class D2I extends ConversionInstruction { - /** Convert double to int + /** + * Convert double to int */ public D2I() { super(com.sun.org.apache.bcel.internal.Const.D2I); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/D2L.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * D2L - Convert double to long - *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    + * 
    */ public class D2L extends ConversionInstruction { - /** Convert double to long + /** + * Convert double to long */ public D2L() { super(com.sun.org.apache.bcel.internal.Const.D2L); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DADD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,29 +23,30 @@ /** * DADD - Add doubles - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result1.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result1.word2 */ public class DADD extends ArithmeticInstruction { - /** Add doubles + /** + * Add doubles */ public DADD() { super(com.sun.org.apache.bcel.internal.Const.DADD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * DALOAD - Load double from array - *
    Stack: ..., arrayref, index -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., arrayref, index -> ..., result.word1, result.word2
    + * 
    */ public class DALOAD extends ArrayInstruction implements StackProducer { - /** Load double from array + /** + * Load double from array */ public DALOAD() { super(com.sun.org.apache.bcel.internal.Const.DALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * DASTORE - Store into double array - *
    Stack: ..., arrayref, index, value.word1, value.word2 -> ...
    + * DASTORE - Store into double array * + *
    + * Stack: ..., arrayref, index, value.word1, value.word2 -> ...
    + * 
    */ public class DASTORE extends ArrayInstruction implements StackConsumer { - /** Store double into array + /** + * Store double into array */ public DASTORE() { super(com.sun.org.apache.bcel.internal.Const.DASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPG.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DCMPG - Compare doubles: value1 > value2 - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
    * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
    + * 
    */ public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { @@ -32,26 +34,25 @@ super(com.sun.org.apache.bcel.internal.Const.DCMPG, (short) 1); } - /** @return Type.DOUBLE - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.DOUBLE; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); v.visitDCMPG(this); } + + /** + * @return Type.DOUBLE + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.DOUBLE; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCMPL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DCMPL - Compare doubles: value1 < value2 - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
    * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result
    + * 
    */ public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { @@ -32,26 +34,25 @@ super(com.sun.org.apache.bcel.internal.Const.DCMPL, (short) 1); } - /** @return Type.DOUBLE - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.DOUBLE; - } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); v.visitDCMPL(this); } + + /** + * @return Type.DOUBLE + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.DOUBLE; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DCONST.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,23 +23,22 @@ /** * DCONST - Push 0.0 or 1.0, other values cause an exception * - *
    Stack: ... -> ..., 
    - * + *
    + * Stack: ... -> ...,
    + * 
    * @LastModified: Jan 2020 */ public class DCONST extends Instruction implements ConstantPushInstruction { - private double value; - + private final double value; /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ DCONST() { + this(0); } - public DCONST(final double f) { super(com.sun.org.apache.bcel.internal.Const.DCONST_0, (short) 1); if (f == 0.0) { @@ -52,35 +51,31 @@ value = f; } - - @Override - public Number getValue() { - return value; - } - - - /** @return Type.DOUBLE - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.DOUBLE; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitPushInstruction(this); v.visitStackProducer(this); v.visitTypedInstruction(this); v.visitConstantPushInstruction(this); v.visitDCONST(this); } + + /** + * @return Type.DOUBLE + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.DOUBLE; + } + + @Override + public Number getValue() { + return Double.valueOf(value); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DDIV.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,30 +22,31 @@ package com.sun.org.apache.bcel.internal.generic; /** - * DDIV - Divide doubles - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 + * DDIV - Divide doubles * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class DDIV extends ArithmeticInstruction { - /** Divide doubles + /** + * Divide doubles */ public DDIV() { super(com.sun.org.apache.bcel.internal.Const.DDIV); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DLOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,38 +23,37 @@ /** * DLOAD - Load double from local variable - *
    Stack ... -> ..., result.word1, result.word2
    * + *
    + * Stack ... -> ..., result.word1, result.word2
    + * 
    */ public class DLOAD extends LoadInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ DLOAD() { super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0); } - - /** Load double from local variable + /** + * Load double from local variable + * * @param n index of local variable */ public DLOAD(final int n) { super(com.sun.org.apache.bcel.internal.Const.DLOAD, com.sun.org.apache.bcel.internal.Const.DLOAD_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitDLOAD(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DMUL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,29 +23,30 @@ /** * DMUL - Multiply doubles - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class DMUL extends ArithmeticInstruction { - /** Multiply doubles + /** + * Multiply doubles */ public DMUL() { super(com.sun.org.apache.bcel.internal.Const.DMUL); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DNEG.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DNEG - Negate double - *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    + * 
    */ public class DNEG extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DNEG); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DREM.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,29 +23,30 @@ /** * DREM - Remainder of doubles - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class DREM extends ArithmeticInstruction { - /** Remainder of doubles + /** + * Remainder of doubles */ public DREM() { super(com.sun.org.apache.bcel.internal.Const.DREM); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DRETURN.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * DRETURN - Return double from method - *
    Stack: ..., value.word1, value.word2 -> <empty>
    + * DRETURN - Return double from method * + *
    + * Stack: ..., value.word1, value.word2 -> <empty>
    + * 
    */ public class DRETURN extends ReturnInstruction { - /** Return double from method + /** + * Return double from method */ public DRETURN() { super(com.sun.org.apache.bcel.internal.Const.DRETURN); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,38 +23,37 @@ /** * DSTORE - Store double into local variable - *
    Stack: ..., value.word1, value.word2 -> ... 
    * + *
    + * Stack: ..., value.word1, value.word2 -> ...
    + * 
    */ public class DSTORE extends StoreInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ DSTORE() { super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0); } - - /** Store double into local variable + /** + * Store double into local variable + * * @param n index of local variable */ public DSTORE(final int n) { super(com.sun.org.apache.bcel.internal.Const.DSTORE, com.sun.org.apache.bcel.internal.Const.DSTORE_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitDSTORE(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DSUB.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,29 +23,30 @@ /** * DSUB - Substract doubles - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class DSUB extends ArithmeticInstruction { - /** Substract doubles + /** + * Substract doubles */ public DSUB() { super(com.sun.org.apache.bcel.internal.Const.DSUB); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DUP2 - Duplicate two top operand stack words - *
    Stack: ..., word2, word1 -> ..., word2, word1, word2, word1
    * + *
    + * Stack: ..., word2, word1 -> ..., word2, word1, word2, word1
    + * 
    */ public class DUP2 extends StackInstruction implements PushInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DUP2); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitPushInstruction(this); v.visitStackInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X1.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DUP2_X1 - Duplicate two top operand stack words and put three down - *
    Stack: ..., word3, word2, word1 -> ..., word2, word1, word3, word2, word1
    * + *
    + * Stack: ..., word3, word2, word1 -> ..., word2, word1, word3, word2, word1
    + * 
    */ public class DUP2_X1 extends StackInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DUP2_X1); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackInstruction(this); v.visitDUP2_X1(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP2_X2.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DUP2_X2 - Duplicate two top operand stack words and put four down - *
    Stack: ..., word4, word3, word2, word1 -> ..., word2, word1, word4, word3, word2, word1
    * + *
    + * Stack: ..., word4, word3, word2, word1 -> ..., word2, word1, word4, word3, word2, word1
    + * 
    */ public class DUP2_X2 extends StackInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DUP2_X2); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackInstruction(this); v.visitDUP2_X2(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DUP - Duplicate top operand stack word - *
    Stack: ..., word -> ..., word, word
    * + *
    + * Stack: ..., word -> ..., word, word
    + * 
    */ public class DUP extends StackInstruction implements PushInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DUP); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitPushInstruction(this); v.visitStackInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X1.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DUP_X1 - Duplicate top operand stack word and put two down - *
    Stack: ..., word2, word1 -> ..., word1, word2, word1
    * + *
    + * Stack: ..., word2, word1 -> ..., word1, word2, word1
    + * 
    */ public class DUP_X1 extends StackInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DUP_X1); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackInstruction(this); v.visitDUP_X1(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/DUP_X2.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * DUP_X2 - Duplicate top operand stack word and put three down - *
    Stack: ..., word3, word2, word1 -> ..., word1, word3, word2, word1
    * + *
    + * Stack: ..., word3, word2, word1 -> ..., word1, word3, word2, word1
    + * 
    */ public class DUP_X2 extends StackInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.DUP_X2); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackInstruction(this); v.visitDUP_X2(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValueGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -36,31 +36,7 @@ * @since 6.0 * @LastModified: May 2021 */ -public abstract class ElementValueGen -{ - private final int type; - private final ConstantPoolGen cpGen; - - protected ElementValueGen(final int type, final ConstantPoolGen cpGen) - { - this.type = type; - this.cpGen = cpGen; - } - - /** - * Subtypes return an immutable variant of the ElementValueGen - */ - public abstract ElementValue getElementValue(); - - public int getElementValueType() - { - return type; - } - - public abstract String stringifyValue(); - - public abstract void dump(DataOutputStream dos) throws IOException; - +public abstract class ElementValueGen { public static final int STRING = 's'; public static final int ENUM_CONSTANT = 'e'; @@ -87,57 +63,69 @@ public static final int PRIMITIVE_BOOLEAN = 'Z'; - public static ElementValueGen readElementValue(final DataInput dis, - final ConstantPoolGen cpGen) throws IOException - { + /** + * Creates an (modifiable) ElementValueGen copy of an (immutable) ElementValue - constant pool is assumed correct. + */ + public static ElementValueGen copy(final ElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + switch (value.getElementValueType()) { + case 'B': // byte + case 'C': // char + case 'D': // double + case 'F': // float + case 'I': // int + case 'J': // long + case 'S': // short + case 'Z': // boolean + case 's': // String + return new SimpleElementValueGen((SimpleElementValue) value, cpool, copyPoolEntries); + case 'e': // Enum constant + return new EnumElementValueGen((EnumElementValue) value, cpool, copyPoolEntries); + case '@': // Annotation + return new AnnotationElementValueGen((AnnotationElementValue) value, cpool, copyPoolEntries); + case '[': // Array + return new ArrayElementValueGen((ArrayElementValue) value, cpool, copyPoolEntries); + case 'c': // Class + return new ClassElementValueGen((ClassElementValue) value, cpool, copyPoolEntries); + default: + throw new UnsupportedOperationException("Not implemented yet! (" + value.getElementValueType() + ")"); + } + } + + public static ElementValueGen readElementValue(final DataInput dis, final ConstantPoolGen cpGen) throws IOException { final int type = dis.readUnsignedByte(); - switch (type) - { + switch (type) { case 'B': // byte - return new SimpleElementValueGen(PRIMITIVE_BYTE, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_BYTE, dis.readUnsignedShort(), cpGen); case 'C': // char - return new SimpleElementValueGen(PRIMITIVE_CHAR, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_CHAR, dis.readUnsignedShort(), cpGen); case 'D': // double - return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis.readUnsignedShort(), cpGen); case 'F': // float - return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis.readUnsignedShort(), cpGen); case 'I': // int - return new SimpleElementValueGen(PRIMITIVE_INT, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_INT, dis.readUnsignedShort(), cpGen); case 'J': // long - return new SimpleElementValueGen(PRIMITIVE_LONG, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_LONG, dis.readUnsignedShort(), cpGen); case 'S': // short - return new SimpleElementValueGen(PRIMITIVE_SHORT, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_SHORT, dis.readUnsignedShort(), cpGen); case 'Z': // boolean - return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis - .readUnsignedShort(), cpGen); + return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis.readUnsignedShort(), cpGen); case 's': // String - return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), - cpGen); + return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), cpGen); case 'e': // Enum constant - return new EnumElementValueGen(dis.readUnsignedShort(), dis - .readUnsignedShort(), cpGen); + return new EnumElementValueGen(dis.readUnsignedShort(), dis.readUnsignedShort(), cpGen); case 'c': // Class return new ClassElementValueGen(dis.readUnsignedShort(), cpGen); case '@': // Annotation // TODO: isRuntimeVisible ?????????? // FIXME - return new AnnotationElementValueGen(ANNOTATION, - new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen - .getConstantPool(), true), cpGen, false), cpGen); + return new AnnotationElementValueGen(ANNOTATION, new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen.getConstantPool(), true), cpGen, false), + cpGen); case '[': // Array final int numArrayVals = dis.readUnsignedShort(); final ElementValue[] evalues = new ElementValue[numArrayVals]; - for (int j = 0; j < numArrayVals; j++) - { - evalues[j] = ElementValue.readElementValue(dis, cpGen - .getConstantPool()); + for (int j = 0; j < numArrayVals; j++) { + evalues[j] = ElementValue.readElementValue(dis, cpGen.getConstantPool()); } return new ArrayElementValueGen(ARRAY, evalues, cpGen); default: @@ -145,45 +133,37 @@ } } - protected ConstantPoolGen getConstantPool() - { + /** + * @deprecated (since 6.0) will be made private and final; do not access directly, use getter + */ + @Deprecated + protected int type; + + /** + * @deprecated (since 6.0) will be made private and final; do not access directly, use getter + */ + @Deprecated + protected ConstantPoolGen cpGen; + + protected ElementValueGen(final int type, final ConstantPoolGen cpGen) { + this.type = type; + this.cpGen = cpGen; + } + + public abstract void dump(DataOutputStream dos) throws IOException; + + protected ConstantPoolGen getConstantPool() { return cpGen; } /** - * Creates an (modifiable) ElementValueGen copy of an (immutable) - * ElementValue - constant pool is assumed correct. + * Subtypes return an immutable variant of the ElementValueGen */ - public static ElementValueGen copy(final ElementValue value, - final ConstantPoolGen cpool, final boolean copyPoolEntries) - { - switch (value.getElementValueType()) - { - case 'B': // byte - case 'C': // char - case 'D': // double - case 'F': // float - case 'I': // int - case 'J': // long - case 'S': // short - case 'Z': // boolean - case 's': // String - return new SimpleElementValueGen((SimpleElementValue) value, cpool, - copyPoolEntries); - case 'e': // Enum constant - return new EnumElementValueGen((EnumElementValue) value, cpool, - copyPoolEntries); - case '@': // Annotation - return new AnnotationElementValueGen( - (AnnotationElementValue) value, cpool, copyPoolEntries); - case '[': // Array - return new ArrayElementValueGen((ArrayElementValue) value, cpool, - copyPoolEntries); - case 'c': // Class - return new ClassElementValueGen((ClassElementValue) value, cpool, - copyPoolEntries); - default: - throw new UnsupportedOperationException("Not implemented yet! (" + value.getElementValueType() + ")"); - } + public abstract ElementValue getElementValue(); + + public int getElementValueType() { + return type; } + + public abstract String stringifyValue(); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ElementValuePairGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,17 +31,14 @@ /** * @since 6.0 */ -public class ElementValuePairGen -{ - private int nameIdx; +public class ElementValuePairGen { + private final int nameIdx; private final ElementValueGen value; private final ConstantPoolGen constantPoolGen; - public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpool, - final boolean copyPoolEntries) - { + public ElementValuePairGen(final ElementValuePair nvp, final ConstantPoolGen cpool, final boolean copyPoolEntries) { this.constantPoolGen = cpool; // J5ASSERT: // Could assert nvp.getNameString() points to the same thing as @@ -51,69 +48,54 @@ // { // throw new IllegalArgumentException("envp buggered"); // } - if (copyPoolEntries) - { + if (copyPoolEntries) { nameIdx = cpool.addUtf8(nvp.getNameString()); - } - else - { + } else { nameIdx = nvp.getNameIndex(); } value = ElementValueGen.copy(nvp.getValue(), cpool, copyPoolEntries); } - /** - * Retrieve an immutable version of this ElementNameValuePairGen - */ - public ElementValuePair getElementNameValuePair() - { - final ElementValue immutableValue = value.getElementValue(); - return new ElementValuePair(nameIdx, immutableValue, constantPoolGen - .getConstantPool()); - } - - protected ElementValuePairGen(final int idx, final ElementValueGen value, - final ConstantPoolGen cpool) - { + protected ElementValuePairGen(final int idx, final ElementValueGen value, final ConstantPoolGen cpool) { this.nameIdx = idx; this.value = value; this.constantPoolGen = cpool; } - public ElementValuePairGen(final String name, final ElementValueGen value, - final ConstantPoolGen cpool) - { + public ElementValuePairGen(final String name, final ElementValueGen value, final ConstantPoolGen cpool) { this.nameIdx = cpool.addUtf8(name); this.value = value; this.constantPoolGen = cpool; } - protected void dump(final DataOutputStream dos) throws IOException - { + protected void dump(final DataOutputStream dos) throws IOException { dos.writeShort(nameIdx); // u2 name of the element value.dump(dos); } - public int getNameIndex() - { + /** + * Retrieve an immutable version of this ElementNameValuePairGen + */ + public ElementValuePair getElementNameValuePair() { + final ElementValue immutableValue = value.getElementValue(); + return new ElementValuePair(nameIdx, immutableValue, constantPoolGen.getConstantPool()); + } + + public int getNameIndex() { return nameIdx; } - public final String getNameString() - { + public final String getNameString() { // ConstantString cu8 = (ConstantString)constantPoolGen.getConstant(nameIdx); return ((ConstantUtf8) constantPoolGen.getConstant(nameIdx)).getBytes(); } - public final ElementValueGen getValue() - { + public final ElementValueGen getValue() { return value; } @Override - public String toString() - { - return "ElementValuePair:[" + getNameString() + "=" - + value.stringifyValue() + "]"; + public String toString() { + return "ElementValuePair:[" + getNameString() + "=" + value.stringifyValue() + "]"; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EmptyVisitor.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,913 +23,733 @@ /** * Supplies empty method bodies to be overridden by subclasses. - * */ public abstract class EmptyVisitor implements Visitor { @Override - public void visitStackInstruction( final StackInstruction obj ) { + public void visitAALOAD(final AALOAD obj) { } - @Override - public void visitLocalVariableInstruction( final LocalVariableInstruction obj ) { + public void visitAASTORE(final AASTORE obj) { } - @Override - public void visitBranchInstruction( final BranchInstruction obj ) { + public void visitACONST_NULL(final ACONST_NULL obj) { } - @Override - public void visitLoadClass( final LoadClass obj ) { + public void visitAllocationInstruction(final AllocationInstruction obj) { } - @Override - public void visitFieldInstruction( final FieldInstruction obj ) { + public void visitALOAD(final ALOAD obj) { } - @Override - public void visitIfInstruction( final IfInstruction obj ) { + public void visitANEWARRAY(final ANEWARRAY obj) { } - @Override - public void visitConversionInstruction( final ConversionInstruction obj ) { + public void visitARETURN(final ARETURN obj) { } - @Override - public void visitPopInstruction( final PopInstruction obj ) { + public void visitArithmeticInstruction(final ArithmeticInstruction obj) { } - @Override - public void visitJsrInstruction( final JsrInstruction obj ) { + public void visitArrayInstruction(final ArrayInstruction obj) { } - @Override - public void visitGotoInstruction( final GotoInstruction obj ) { + public void visitARRAYLENGTH(final ARRAYLENGTH obj) { } - @Override - public void visitStoreInstruction( final StoreInstruction obj ) { + public void visitASTORE(final ASTORE obj) { } - @Override - public void visitTypedInstruction( final TypedInstruction obj ) { + public void visitATHROW(final ATHROW obj) { } - @Override - public void visitSelect( final Select obj ) { + public void visitBALOAD(final BALOAD obj) { } - @Override - public void visitUnconditionalBranch( final UnconditionalBranch obj ) { + public void visitBASTORE(final BASTORE obj) { } - @Override - public void visitPushInstruction( final PushInstruction obj ) { + public void visitBIPUSH(final BIPUSH obj) { } - @Override - public void visitArithmeticInstruction( final ArithmeticInstruction obj ) { + public void visitBranchInstruction(final BranchInstruction obj) { } - @Override - public void visitCPInstruction( final CPInstruction obj ) { + public void visitBREAKPOINT(final BREAKPOINT obj) { } - @Override - public void visitInvokeInstruction( final InvokeInstruction obj ) { + public void visitCALOAD(final CALOAD obj) { } - @Override - public void visitArrayInstruction( final ArrayInstruction obj ) { + public void visitCASTORE(final CASTORE obj) { } - @Override - public void visitAllocationInstruction( final AllocationInstruction obj ) { + public void visitCHECKCAST(final CHECKCAST obj) { } - @Override - public void visitReturnInstruction( final ReturnInstruction obj ) { + public void visitConstantPushInstruction(final ConstantPushInstruction obj) { } - @Override - public void visitFieldOrMethod( final FieldOrMethod obj ) { + public void visitConversionInstruction(final ConversionInstruction obj) { } - @Override - public void visitConstantPushInstruction( final ConstantPushInstruction obj ) { + public void visitCPInstruction(final CPInstruction obj) { } - @Override - public void visitExceptionThrower( final ExceptionThrower obj ) { + public void visitD2F(final D2F obj) { } - @Override - public void visitLoadInstruction( final LoadInstruction obj ) { + public void visitD2I(final D2I obj) { } - @Override - public void visitVariableLengthInstruction( final VariableLengthInstruction obj ) { + public void visitD2L(final D2L obj) { } - @Override - public void visitStackProducer( final StackProducer obj ) { + public void visitDADD(final DADD obj) { } - @Override - public void visitStackConsumer( final StackConsumer obj ) { + public void visitDALOAD(final DALOAD obj) { } - @Override - public void visitACONST_NULL( final ACONST_NULL obj ) { + public void visitDASTORE(final DASTORE obj) { } - @Override - public void visitGETSTATIC( final GETSTATIC obj ) { + public void visitDCMPG(final DCMPG obj) { } - @Override - public void visitIF_ICMPLT( final IF_ICMPLT obj ) { + public void visitDCMPL(final DCMPL obj) { } - @Override - public void visitMONITOREXIT( final MONITOREXIT obj ) { + public void visitDCONST(final DCONST obj) { } - @Override - public void visitIFLT( final IFLT obj ) { + public void visitDDIV(final DDIV obj) { } - @Override - public void visitLSTORE( final LSTORE obj ) { + public void visitDLOAD(final DLOAD obj) { } - @Override - public void visitPOP2( final POP2 obj ) { + public void visitDMUL(final DMUL obj) { } - @Override - public void visitBASTORE( final BASTORE obj ) { + public void visitDNEG(final DNEG obj) { } - @Override - public void visitISTORE( final ISTORE obj ) { + public void visitDREM(final DREM obj) { } - @Override - public void visitCHECKCAST( final CHECKCAST obj ) { + public void visitDRETURN(final DRETURN obj) { } - @Override - public void visitFCMPG( final FCMPG obj ) { + public void visitDSTORE(final DSTORE obj) { } - @Override - public void visitI2F( final I2F obj ) { + public void visitDSUB(final DSUB obj) { } - @Override - public void visitATHROW( final ATHROW obj ) { + public void visitDUP(final DUP obj) { } - @Override - public void visitDCMPL( final DCMPL obj ) { + public void visitDUP_X1(final DUP_X1 obj) { } - @Override - public void visitARRAYLENGTH( final ARRAYLENGTH obj ) { + public void visitDUP_X2(final DUP_X2 obj) { } - @Override - public void visitDUP( final DUP obj ) { + public void visitDUP2(final DUP2 obj) { } - @Override - public void visitINVOKESTATIC( final INVOKESTATIC obj ) { + public void visitDUP2_X1(final DUP2_X1 obj) { } - @Override - public void visitLCONST( final LCONST obj ) { + public void visitDUP2_X2(final DUP2_X2 obj) { } - @Override - public void visitDREM( final DREM obj ) { + public void visitExceptionThrower(final ExceptionThrower obj) { } - @Override - public void visitIFGE( final IFGE obj ) { + public void visitF2D(final F2D obj) { } - @Override - public void visitCALOAD( final CALOAD obj ) { + public void visitF2I(final F2I obj) { } - @Override - public void visitLASTORE( final LASTORE obj ) { + public void visitF2L(final F2L obj) { } - @Override - public void visitI2D( final I2D obj ) { + public void visitFADD(final FADD obj) { } - @Override - public void visitDADD( final DADD obj ) { + public void visitFALOAD(final FALOAD obj) { } - @Override - public void visitINVOKESPECIAL( final INVOKESPECIAL obj ) { + public void visitFASTORE(final FASTORE obj) { } - @Override - public void visitIAND( final IAND obj ) { + public void visitFCMPG(final FCMPG obj) { } - @Override - public void visitPUTFIELD( final PUTFIELD obj ) { + public void visitFCMPL(final FCMPL obj) { } - @Override - public void visitILOAD( final ILOAD obj ) { + public void visitFCONST(final FCONST obj) { } - @Override - public void visitDLOAD( final DLOAD obj ) { + public void visitFDIV(final FDIV obj) { } - @Override - public void visitDCONST( final DCONST obj ) { + public void visitFieldInstruction(final FieldInstruction obj) { } - @Override - public void visitNEW( final NEW obj ) { + public void visitFieldOrMethod(final FieldOrMethod obj) { } - @Override - public void visitIFNULL( final IFNULL obj ) { + public void visitFLOAD(final FLOAD obj) { } - @Override - public void visitLSUB( final LSUB obj ) { + public void visitFMUL(final FMUL obj) { } - @Override - public void visitL2I( final L2I obj ) { + public void visitFNEG(final FNEG obj) { } - @Override - public void visitISHR( final ISHR obj ) { + public void visitFREM(final FREM obj) { } - @Override - public void visitTABLESWITCH( final TABLESWITCH obj ) { + public void visitFRETURN(final FRETURN obj) { } - @Override - public void visitIINC( final IINC obj ) { + public void visitFSTORE(final FSTORE obj) { } - @Override - public void visitDRETURN( final DRETURN obj ) { + public void visitFSUB(final FSUB obj) { } - @Override - public void visitFSTORE( final FSTORE obj ) { + public void visitGETFIELD(final GETFIELD obj) { } - @Override - public void visitDASTORE( final DASTORE obj ) { + public void visitGETSTATIC(final GETSTATIC obj) { } - @Override - public void visitIALOAD( final IALOAD obj ) { + public void visitGOTO(final GOTO obj) { } - @Override - public void visitDDIV( final DDIV obj ) { + public void visitGOTO_W(final GOTO_W obj) { } - @Override - public void visitIF_ICMPGE( final IF_ICMPGE obj ) { + public void visitGotoInstruction(final GotoInstruction obj) { } - @Override - public void visitLAND( final LAND obj ) { + public void visitI2B(final I2B obj) { } - @Override - public void visitIDIV( final IDIV obj ) { + public void visitI2C(final I2C obj) { } - @Override - public void visitLOR( final LOR obj ) { + public void visitI2D(final I2D obj) { } - @Override - public void visitCASTORE( final CASTORE obj ) { + public void visitI2F(final I2F obj) { } - @Override - public void visitFREM( final FREM obj ) { + public void visitI2L(final I2L obj) { } - @Override - public void visitLDC( final LDC obj ) { + public void visitI2S(final I2S obj) { } - @Override - public void visitBIPUSH( final BIPUSH obj ) { + public void visitIADD(final IADD obj) { } - @Override - public void visitDSTORE( final DSTORE obj ) { + public void visitIALOAD(final IALOAD obj) { } - @Override - public void visitF2L( final F2L obj ) { + public void visitIAND(final IAND obj) { } - @Override - public void visitFMUL( final FMUL obj ) { + public void visitIASTORE(final IASTORE obj) { } - @Override - public void visitLLOAD( final LLOAD obj ) { + public void visitICONST(final ICONST obj) { } - @Override - public void visitJSR( final JSR obj ) { + public void visitIDIV(final IDIV obj) { } - @Override - public void visitFSUB( final FSUB obj ) { + public void visitIF_ACMPEQ(final IF_ACMPEQ obj) { } - @Override - public void visitSASTORE( final SASTORE obj ) { + public void visitIF_ACMPNE(final IF_ACMPNE obj) { } - @Override - public void visitALOAD( final ALOAD obj ) { + public void visitIF_ICMPEQ(final IF_ICMPEQ obj) { } - @Override - public void visitDUP2_X2( final DUP2_X2 obj ) { + public void visitIF_ICMPGE(final IF_ICMPGE obj) { } - @Override - public void visitRETURN( final RETURN obj ) { + public void visitIF_ICMPGT(final IF_ICMPGT obj) { } - @Override - public void visitDALOAD( final DALOAD obj ) { + public void visitIF_ICMPLE(final IF_ICMPLE obj) { } - @Override - public void visitSIPUSH( final SIPUSH obj ) { + public void visitIF_ICMPLT(final IF_ICMPLT obj) { } - @Override - public void visitDSUB( final DSUB obj ) { + public void visitIF_ICMPNE(final IF_ICMPNE obj) { } - @Override - public void visitL2F( final L2F obj ) { + public void visitIFEQ(final IFEQ obj) { } - @Override - public void visitIF_ICMPGT( final IF_ICMPGT obj ) { + public void visitIFGE(final IFGE obj) { } - @Override - public void visitF2D( final F2D obj ) { + public void visitIFGT(final IFGT obj) { } - @Override - public void visitI2L( final I2L obj ) { + public void visitIfInstruction(final IfInstruction obj) { } - @Override - public void visitIF_ACMPNE( final IF_ACMPNE obj ) { + public void visitIFLE(final IFLE obj) { } - @Override - public void visitPOP( final POP obj ) { + public void visitIFLT(final IFLT obj) { } - @Override - public void visitI2S( final I2S obj ) { + public void visitIFNE(final IFNE obj) { } - @Override - public void visitIFEQ( final IFEQ obj ) { + public void visitIFNONNULL(final IFNONNULL obj) { } - @Override - public void visitSWAP( final SWAP obj ) { + public void visitIFNULL(final IFNULL obj) { } - @Override - public void visitIOR( final IOR obj ) { + public void visitIINC(final IINC obj) { } - @Override - public void visitIREM( final IREM obj ) { + public void visitILOAD(final ILOAD obj) { } - @Override - public void visitIASTORE( final IASTORE obj ) { + public void visitIMPDEP1(final IMPDEP1 obj) { } - @Override - public void visitNEWARRAY( final NEWARRAY obj ) { + public void visitIMPDEP2(final IMPDEP2 obj) { } - @Override - public void visitINVOKEINTERFACE( final INVOKEINTERFACE obj ) { + public void visitIMUL(final IMUL obj) { } - @Override - public void visitINEG( final INEG obj ) { + public void visitINEG(final INEG obj) { } - @Override - public void visitLCMP( final LCMP obj ) { + public void visitINSTANCEOF(final INSTANCEOF obj) { } - + /** + * @since 6.0 + */ @Override - public void visitJSR_W( final JSR_W obj ) { + public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC obj) { } - @Override - public void visitMULTIANEWARRAY( final MULTIANEWARRAY obj ) { + public void visitInvokeInstruction(final InvokeInstruction obj) { } - @Override - public void visitDUP_X2( final DUP_X2 obj ) { + public void visitINVOKEINTERFACE(final INVOKEINTERFACE obj) { } - @Override - public void visitSALOAD( final SALOAD obj ) { + public void visitINVOKESPECIAL(final INVOKESPECIAL obj) { } - @Override - public void visitIFNONNULL( final IFNONNULL obj ) { + public void visitINVOKESTATIC(final INVOKESTATIC obj) { } - @Override - public void visitDMUL( final DMUL obj ) { + public void visitINVOKEVIRTUAL(final INVOKEVIRTUAL obj) { } - @Override - public void visitIFNE( final IFNE obj ) { + public void visitIOR(final IOR obj) { } - @Override - public void visitIF_ICMPLE( final IF_ICMPLE obj ) { + public void visitIREM(final IREM obj) { } - @Override - public void visitLDC2_W( final LDC2_W obj ) { + public void visitIRETURN(final IRETURN obj) { } - @Override - public void visitGETFIELD( final GETFIELD obj ) { + public void visitISHL(final ISHL obj) { } - @Override - public void visitLADD( final LADD obj ) { + public void visitISHR(final ISHR obj) { } - @Override - public void visitNOP( final NOP obj ) { + public void visitISTORE(final ISTORE obj) { } - @Override - public void visitFALOAD( final FALOAD obj ) { + public void visitISUB(final ISUB obj) { } - @Override - public void visitINSTANCEOF( final INSTANCEOF obj ) { + public void visitIUSHR(final IUSHR obj) { } - @Override - public void visitIFLE( final IFLE obj ) { + public void visitIXOR(final IXOR obj) { } - @Override - public void visitLXOR( final LXOR obj ) { + public void visitJSR(final JSR obj) { } - @Override - public void visitLRETURN( final LRETURN obj ) { + public void visitJSR_W(final JSR_W obj) { } - @Override - public void visitFCONST( final FCONST obj ) { + public void visitJsrInstruction(final JsrInstruction obj) { } - @Override - public void visitIUSHR( final IUSHR obj ) { + public void visitL2D(final L2D obj) { } - @Override - public void visitBALOAD( final BALOAD obj ) { + public void visitL2F(final L2F obj) { } - @Override - public void visitDUP2( final DUP2 obj ) { + public void visitL2I(final L2I obj) { } - @Override - public void visitIF_ACMPEQ( final IF_ACMPEQ obj ) { + public void visitLADD(final LADD obj) { } - @Override - public void visitIMPDEP1( final IMPDEP1 obj ) { + public void visitLALOAD(final LALOAD obj) { } - @Override - public void visitMONITORENTER( final MONITORENTER obj ) { + public void visitLAND(final LAND obj) { } - @Override - public void visitLSHL( final LSHL obj ) { + public void visitLASTORE(final LASTORE obj) { } - @Override - public void visitDCMPG( final DCMPG obj ) { + public void visitLCMP(final LCMP obj) { } - @Override - public void visitD2L( final D2L obj ) { + public void visitLCONST(final LCONST obj) { } - @Override - public void visitIMPDEP2( final IMPDEP2 obj ) { + public void visitLDC(final LDC obj) { } - @Override - public void visitL2D( final L2D obj ) { + public void visitLDC2_W(final LDC2_W obj) { } - @Override - public void visitRET( final RET obj ) { + public void visitLDIV(final LDIV obj) { } - @Override - public void visitIFGT( final IFGT obj ) { + public void visitLLOAD(final LLOAD obj) { } - @Override - public void visitIXOR( final IXOR obj ) { + public void visitLMUL(final LMUL obj) { } - @Override - public void visitINVOKEVIRTUAL( final INVOKEVIRTUAL obj ) { + public void visitLNEG(final LNEG obj) { } - @Override - public void visitFASTORE( final FASTORE obj ) { + public void visitLoadClass(final LoadClass obj) { } - @Override - public void visitIRETURN( final IRETURN obj ) { + public void visitLoadInstruction(final LoadInstruction obj) { } - @Override - public void visitIF_ICMPNE( final IF_ICMPNE obj ) { + public void visitLocalVariableInstruction(final LocalVariableInstruction obj) { } - @Override - public void visitFLOAD( final FLOAD obj ) { + public void visitLOOKUPSWITCH(final LOOKUPSWITCH obj) { } - @Override - public void visitLDIV( final LDIV obj ) { + public void visitLOR(final LOR obj) { } - @Override - public void visitPUTSTATIC( final PUTSTATIC obj ) { + public void visitLREM(final LREM obj) { } - @Override - public void visitAALOAD( final AALOAD obj ) { + public void visitLRETURN(final LRETURN obj) { } - @Override - public void visitD2I( final D2I obj ) { + public void visitLSHL(final LSHL obj) { } - @Override - public void visitIF_ICMPEQ( final IF_ICMPEQ obj ) { + public void visitLSHR(final LSHR obj) { } - @Override - public void visitAASTORE( final AASTORE obj ) { + public void visitLSTORE(final LSTORE obj) { } - @Override - public void visitARETURN( final ARETURN obj ) { + public void visitLSUB(final LSUB obj) { } - @Override - public void visitDUP2_X1( final DUP2_X1 obj ) { + public void visitLUSHR(final LUSHR obj) { } - @Override - public void visitFNEG( final FNEG obj ) { + public void visitLXOR(final LXOR obj) { } - @Override - public void visitGOTO_W( final GOTO_W obj ) { + public void visitMONITORENTER(final MONITORENTER obj) { } - @Override - public void visitD2F( final D2F obj ) { + public void visitMONITOREXIT(final MONITOREXIT obj) { } - @Override - public void visitGOTO( final GOTO obj ) { + public void visitMULTIANEWARRAY(final MULTIANEWARRAY obj) { } - @Override - public void visitISUB( final ISUB obj ) { + public void visitNEW(final NEW obj) { } - @Override - public void visitF2I( final F2I obj ) { + public void visitNEWARRAY(final NEWARRAY obj) { } - @Override - public void visitDNEG( final DNEG obj ) { + public void visitNOP(final NOP obj) { } - @Override - public void visitICONST( final ICONST obj ) { + public void visitPOP(final POP obj) { } - @Override - public void visitFDIV( final FDIV obj ) { + public void visitPOP2(final POP2 obj) { } - @Override - public void visitI2B( final I2B obj ) { + public void visitPopInstruction(final PopInstruction obj) { } - @Override - public void visitLNEG( final LNEG obj ) { + public void visitPushInstruction(final PushInstruction obj) { } - @Override - public void visitLREM( final LREM obj ) { + public void visitPUTFIELD(final PUTFIELD obj) { } - @Override - public void visitIMUL( final IMUL obj ) { + public void visitPUTSTATIC(final PUTSTATIC obj) { } - @Override - public void visitIADD( final IADD obj ) { + public void visitRET(final RET obj) { } - @Override - public void visitLSHR( final LSHR obj ) { + public void visitRETURN(final RETURN obj) { } - @Override - public void visitLOOKUPSWITCH( final LOOKUPSWITCH obj ) { + public void visitReturnInstruction(final ReturnInstruction obj) { } - @Override - public void visitDUP_X1( final DUP_X1 obj ) { + public void visitSALOAD(final SALOAD obj) { } - @Override - public void visitFCMPL( final FCMPL obj ) { + public void visitSASTORE(final SASTORE obj) { } - @Override - public void visitI2C( final I2C obj ) { + public void visitSelect(final Select obj) { } - @Override - public void visitLMUL( final LMUL obj ) { + public void visitSIPUSH(final SIPUSH obj) { } - @Override - public void visitLUSHR( final LUSHR obj ) { + public void visitStackConsumer(final StackConsumer obj) { } - @Override - public void visitISHL( final ISHL obj ) { + public void visitStackInstruction(final StackInstruction obj) { } - @Override - public void visitLALOAD( final LALOAD obj ) { + public void visitStackProducer(final StackProducer obj) { } - @Override - public void visitASTORE( final ASTORE obj ) { + public void visitStoreInstruction(final StoreInstruction obj) { } - @Override - public void visitANEWARRAY( final ANEWARRAY obj ) { + public void visitSWAP(final SWAP obj) { } - @Override - public void visitFRETURN( final FRETURN obj ) { + public void visitTABLESWITCH(final TABLESWITCH obj) { } - @Override - public void visitFADD( final FADD obj ) { + public void visitTypedInstruction(final TypedInstruction obj) { } - @Override - public void visitBREAKPOINT( final BREAKPOINT obj ) { + public void visitUnconditionalBranch(final UnconditionalBranch obj) { } - /** - * @since 6.0 - */ @Override - public void visitINVOKEDYNAMIC(final INVOKEDYNAMIC obj) { + public void visitVariableLengthInstruction(final VariableLengthInstruction obj) { } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/EnumElementValueGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,103 +31,73 @@ /** * @since 6.0 */ -public class EnumElementValueGen extends ElementValueGen -{ +public class EnumElementValueGen extends ElementValueGen { // For enum types, these two indices point to the type and value - private int typeIdx; + private final int typeIdx; - private int valueIdx; + private final int valueIdx; + + public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { + super(ENUM_CONSTANT, cpool); + if (copyPoolEntries) { + typeIdx = cpool.addUtf8(value.getEnumTypeString());// was + // addClass(value.getEnumTypeString()); + valueIdx = cpool.addUtf8(value.getEnumValueString()); // was + // addString(value.getEnumValueString()); + } else { + typeIdx = value.getTypeIndex(); + valueIdx = value.getValueIndex(); + } + } /** - * This ctor assumes the constant pool already contains the right type and - * value - as indicated by typeIdx and valueIdx. This ctor is used for - * deserialization + * This ctor assumes the constant pool already contains the right type and value - as indicated by typeIdx and valueIdx. + * This ctor is used for deserialization */ - protected EnumElementValueGen(final int typeIdx, final int valueIdx, - final ConstantPoolGen cpool) - { + protected EnumElementValueGen(final int typeIdx, final int valueIdx, final ConstantPoolGen cpool) { super(ElementValueGen.ENUM_CONSTANT, cpool); if (super.getElementValueType() != ENUM_CONSTANT) { - throw new IllegalArgumentException( - "Only element values of type enum can be built with this ctor - type specified: " - + super.getElementValueType()); + throw new IllegalArgumentException("Only element values of type enum can be built with this ctor - type specified: " + super.getElementValueType()); } this.typeIdx = typeIdx; this.valueIdx = valueIdx; } - /** - * Return immutable variant of this EnumElementValue - */ - @Override - public ElementValue getElementValue() - { - System.err.println("Duplicating value: " + getEnumTypeString() + ":" - + getEnumValueString()); - return new EnumElementValue(super.getElementValueType(), typeIdx, valueIdx, - getConstantPool().getConstantPool()); - } - - public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) - { + public EnumElementValueGen(final ObjectType t, final String value, final ConstantPoolGen cpool) { super(ElementValueGen.ENUM_CONSTANT, cpool); typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); valueIdx = cpool.addUtf8(value);// was addString(value); } - public EnumElementValueGen(final EnumElementValue value, final ConstantPoolGen cpool, - final boolean copyPoolEntries) - { - super(ENUM_CONSTANT, cpool); - if (copyPoolEntries) - { - typeIdx = cpool.addUtf8(value.getEnumTypeString());// was - // addClass(value.getEnumTypeString()); - valueIdx = cpool.addUtf8(value.getEnumValueString()); // was - // addString(value.getEnumValueString()); - } - else - { - typeIdx = value.getTypeIndex(); - valueIdx = value.getValueIndex(); - } - } - @Override - public void dump(final DataOutputStream dos) throws IOException - { + public void dump(final DataOutputStream dos) throws IOException { dos.writeByte(super.getElementValueType()); // u1 type of value (ENUM_CONSTANT == 'e') dos.writeShort(typeIdx); // u2 dos.writeShort(valueIdx); // u2 } + /** + * Return immutable variant of this EnumElementValue + */ @Override - public String stringifyValue() - { - final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx); - return cu8.getBytes(); - // ConstantString cu8 = - // (ConstantString)getConstantPool().getConstant(valueIdx); - // return - // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); + public ElementValue getElementValue() { + System.err.println("Duplicating value: " + getEnumTypeString() + ":" + getEnumValueString()); + return new EnumElementValue(super.getElementValueType(), typeIdx, valueIdx, getConstantPool().getConstantPool()); } // BCELBUG: Should we need to call utility.signatureToString() on the output // here? - public String getEnumTypeString() - { + public String getEnumTypeString() { // Constant cc = getConstantPool().getConstant(typeIdx); // ConstantClass cu8 = // (ConstantClass)getConstantPool().getConstant(typeIdx); // return // ((ConstantUtf8)getConstantPool().getConstant(cu8.getNameIndex())).getBytes(); - return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)) - .getBytes(); + return ((ConstantUtf8) getConstantPool().getConstant(typeIdx)).getBytes(); // return Utility.signatureToString(cu8.getBytes()); } - public String getEnumValueString() - { + public String getEnumValueString() { return ((ConstantUtf8) getConstantPool().getConstant(valueIdx)).getBytes(); // ConstantString cu8 = // (ConstantString)getConstantPool().getConstant(valueIdx); @@ -135,13 +105,21 @@ // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); } - public int getValueIndex() - { + public int getTypeIndex() { + return typeIdx; + } + + public int getValueIndex() { return valueIdx; } - public int getTypeIndex() - { - return typeIdx; + @Override + public String stringifyValue() { + final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(valueIdx); + return cu8.getBytes(); + // ConstantString cu8 = + // (ConstantString)getConstantPool().getConstant(valueIdx); + // return + // ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ExceptionThrower.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,24 +22,17 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denote an instruction that may throw a run-time or a linking - * exception (or both) during execution. This is not quite the truth - * as such; because all instructions may throw an - * java.lang.VirtualMachineError. These exceptions are omitted. + * Denote an instruction that may throw a run-time or a linking exception (or both) during execution. This is not quite + * the truth as such; because all instructions may throw an java.lang.VirtualMachineError. These exceptions are omitted. * - * The Lava Language Specification specifies exactly which - * RUN-TIME and which LINKING exceptions each - * instruction may throw which is reflected by the implementers. Due - * to the structure of the JVM specification, it may be possible that - * an Instruction implementing this interface returns a Class[] of - * size 0. - * - * Please note that we speak of an "exception" here when we mean any - * "Throwable" object; so this term is equally used for "Exception" - * and "Error" objects. + * The Lava Language Specification specifies exactly which RUN-TIME and which LINKING exceptions each + * instruction may throw which is reflected by the implementers. Due to the structure of the JVM specification, it may + * be possible that an Instruction implementing this interface returns a Class[] of size 0. * + * Please note that we speak of an "exception" here when we mean any "Throwable" object; so this term is equally used + * for "Exception" and "Error" objects. */ public interface ExceptionThrower { - java.lang.Class[] getExceptions(); + Class[] getExceptions(); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2D.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * F2D - Convert float to double - *
    Stack: ..., value -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value -> ..., result.word1, result.word2
    + * 
    */ public class F2D extends ConversionInstruction { - /** Convert float to double + /** + * Convert float to double */ public F2D() { super(com.sun.org.apache.bcel.internal.Const.F2D); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2I.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * F2I - Convert float to int - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class F2I extends ConversionInstruction { - /** Convert float to int + /** + * Convert float to int */ public F2I() { super(com.sun.org.apache.bcel.internal.Const.F2I); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/F2L.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * F2L - Convert float to long - *
    Stack: ..., value -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value -> ..., result.word1, result.word2
    + * 
    */ public class F2L extends ConversionInstruction { - /** Convert float to long + /** + * Convert float to long */ public F2L() { super(com.sun.org.apache.bcel.internal.Const.F2L); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FADD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * FADD - Add floats - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class FADD extends ArithmeticInstruction { - /** Add floats + /** + * Add floats */ public FADD() { super(com.sun.org.apache.bcel.internal.Const.FADD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * FALOAD - Load float from array - *
    Stack: ..., arrayref, index -> ..., value
    * + *
    + * Stack: ..., arrayref, index -> ..., value
    + * 
    */ public class FALOAD extends ArrayInstruction implements StackProducer { - /** Load float from array + /** + * Load float from array */ public FALOAD() { super(com.sun.org.apache.bcel.internal.Const.FALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * FASTORE - Store into float array - *
    Stack: ..., arrayref, index, value -> ...
    + * FASTORE - Store into float array * + *
    + * Stack: ..., arrayref, index, value -> ...
    + * 
    */ public class FASTORE extends ArrayInstruction implements StackConsumer { - /** Store float into array + /** + * Store float into array */ public FASTORE() { super(com.sun.org.apache.bcel.internal.Const.FASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPG.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * FCMPG - Compare floats: value1 > value2 - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class FCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { @@ -32,28 +34,25 @@ super(com.sun.org.apache.bcel.internal.Const.FCMPG, (short) 1); } - - /** @return Type.FLOAT - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.FLOAT; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); v.visitFCMPG(this); } + + /** + * @return Type.FLOAT + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.FLOAT; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCMPL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * FCMPL - Compare floats: value1 < value2 - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class FCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { @@ -32,28 +34,25 @@ super(com.sun.org.apache.bcel.internal.Const.FCMPL, (short) 1); } - - /** @return Type.FLOAT - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.FLOAT; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); v.visitFCMPL(this); } + + /** + * @return Type.FLOAT + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.FLOAT; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FCONST.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,23 +23,22 @@ /** * FCONST - Push 0.0, 1.0 or 2.0, other values cause an exception * - *
    Stack: ... -> ..., 
    - * + *
    + * Stack: ... -> ...,
    + * 
    * @LastModified: Jan 2020 */ public class FCONST extends Instruction implements ConstantPushInstruction { - private float value; - + private final float value; /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ FCONST() { + this(0); } - public FCONST(final float f) { super(com.sun.org.apache.bcel.internal.Const.FCONST_0, (short) 1); if (f == 0.0) { @@ -54,35 +53,31 @@ value = f; } - - @Override - public Number getValue() { - return value; - } - - - /** @return Type.FLOAT - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.FLOAT; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitPushInstruction(this); v.visitStackProducer(this); v.visitTypedInstruction(this); v.visitConstantPushInstruction(this); v.visitFCONST(this); } + + /** + * @return Type.FLOAT + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.FLOAT; + } + + @Override + public Number getValue() { + return Float.valueOf(value); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FDIV.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * FDIV - Divide floats - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class FDIV extends ArithmeticInstruction { - /** Divide floats + /** + * Divide floats */ public FDIV() { super(com.sun.org.apache.bcel.internal.Const.FDIV); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,9 +22,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.stream.Stream; import com.sun.org.apache.bcel.internal.Const; -import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; import com.sun.org.apache.bcel.internal.classfile.Annotations; import com.sun.org.apache.bcel.internal.classfile.Attribute; import com.sun.org.apache.bcel.internal.classfile.Constant; @@ -36,52 +36,47 @@ import com.sun.org.apache.bcel.internal.util.BCELComparator; /** - * Template class for building up a field. The only extraordinary thing - * one can do is to add a constant value attribute to a field (which must of - * course be compatible with to the declared type). + * Template class for building up a field. The only extraordinary thing one can do is to add a constant value attribute + * to a field (which must of course be compatible with to the declared type). * * @see Field * @LastModified: May 2021 */ public class FieldGen extends FieldGenOrMethodGen { - private Object value = null; private static BCELComparator bcelComparator = new BCELComparator() { @Override - public boolean equals( final Object o1, final Object o2 ) { + public boolean equals(final Object o1, final Object o2) { final FieldGen THIS = (FieldGen) o1; final FieldGen THAT = (FieldGen) o2; - return Objects.equals(THIS.getName(), THAT.getName()) - && Objects.equals(THIS.getSignature(), THAT.getSignature()); + return Objects.equals(THIS.getName(), THAT.getName()) && Objects.equals(THIS.getSignature(), THAT.getSignature()); } - @Override - public int hashCode( final Object o ) { + public int hashCode(final Object o) { final FieldGen THIS = (FieldGen) o; return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); } }; + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } /** - * Declare a field. If it is static (isStatic() == true) and has a - * basic type like int or String it may have an initial value - * associated with it as defined by setInitValue(). - * - * @param access_flags access qualifiers - * @param type field type - * @param name field name - * @param cp constant pool + * @param comparator Comparison strategy object */ - public FieldGen(final int access_flags, final Type type, final String name, final ConstantPoolGen cp) { - super(access_flags); - setType(type); - setName(name); - setConstantPool(cp); + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; } + private Object value; + + private List observers; /** * Instantiate from existing field. @@ -96,109 +91,73 @@ if (attr instanceof ConstantValue) { setValue(((ConstantValue) attr).getConstantValueIndex()); } else if (attr instanceof Annotations) { - final Annotations runtimeAnnotations = (Annotations)attr; - final AnnotationEntry[] annotationEntries = runtimeAnnotations.getAnnotationEntries(); - for (final AnnotationEntry element : annotationEntries) { - addAnnotationEntry(new AnnotationEntryGen(element,cp,false)); - } + final Annotations runtimeAnnotations = (Annotations) attr; + runtimeAnnotations.forEach(element -> addAnnotationEntry(new AnnotationEntryGen(element, cp, false))); } else { addAttribute(attr); } } } - - private void setValue( final int index ) { - final ConstantPool cp = super.getConstantPool().getConstantPool(); - final Constant c = cp.getConstant(index); - value = ((ConstantObject) c).getConstantValue(cp); - } - - /** - * Set (optional) initial value of field, otherwise it will be set to null/0/false - * by the JVM automatically. + * Declare a field. If it is static (isStatic() == true) and has a basic type like int or String it may have an initial + * value associated with it as defined by setInitValue(). + * + * @param accessFlags access qualifiers + * @param type field type + * @param name field name + * @param cp constant pool */ - public void setInitValue( final String str ) { - checkType( ObjectType.getInstance("java.lang.String")); - if (str != null) { - value = str; - } - } - - - public void setInitValue( final long l ) { - checkType(Type.LONG); - if (l != 0L) { - value = Long.valueOf(l); - } - } - - - public void setInitValue( final int i ) { - checkType(Type.INT); - if (i != 0) { - value = Integer.valueOf(i); - } - } - - - public void setInitValue( final short s ) { - checkType(Type.SHORT); - if (s != 0) { - value = Integer.valueOf(s); - } - } - - - public void setInitValue( final char c ) { - checkType(Type.CHAR); - if (c != 0) { - value = Integer.valueOf(c); - } - } - - - public void setInitValue( final byte b ) { - checkType(Type.BYTE); - if (b != 0) { - value = Integer.valueOf(b); - } + public FieldGen(final int accessFlags, final Type type, final String name, final ConstantPoolGen cp) { + super(accessFlags); + setType(type); + setName(name); + setConstantPool(cp); } - - public void setInitValue( final boolean b ) { - checkType(Type.BOOLEAN); - if (b) { - value = Integer.valueOf(1); - } + private void addAnnotationsAsAttribute(final ConstantPoolGen cp) { + Stream.of(AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries())).forEach(this::addAttribute); } - - public void setInitValue( final float f ) { - checkType(Type.FLOAT); - if (f != 0.0) { - value = f; + private int addConstant() { + switch (super.getType().getType()) { // sic + case Const.T_INT: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_BOOLEAN: + case Const.T_SHORT: + return super.getConstantPool().addInteger(((Integer) value).intValue()); + case Const.T_FLOAT: + return super.getConstantPool().addFloat(((Float) value).floatValue()); + case Const.T_DOUBLE: + return super.getConstantPool().addDouble(((Double) value).doubleValue()); + case Const.T_LONG: + return super.getConstantPool().addLong(((Long) value).longValue()); + case Const.T_REFERENCE: + return super.getConstantPool().addString((String) value); + default: + throw new IllegalStateException("Unhandled : " + super.getType().getType()); // sic } } - - public void setInitValue( final double d ) { - checkType(Type.DOUBLE); - if (d != 0.0) { - value = d; + /** + * Add observer for this object. + */ + public void addObserver(final FieldObserver o) { + if (observers == null) { + observers = new ArrayList<>(); } + observers.add(o); } - - /** Remove any initial value. + /** + * Remove any initial value. */ public void cancelInitValue() { value = null; } - - private void checkType( final Type atype ) { + private void checkType(final Type atype) { final Type superType = super.getType(); if (superType == null) { throw new ClassGenException("You haven't defined the type of the field yet"); @@ -211,106 +170,148 @@ } } + /** + * @return deep copy of this field + */ + public FieldGen copy(final ConstantPoolGen cp) { + final FieldGen fg = (FieldGen) clone(); + fg.setConstantPool(cp); + return fg; + } + + /** + * Return value as defined by given BCELComparator strategy. By default two FieldGen objects are said to be equal when + * their names and signatures are equal. + * + * @see Object#equals(Object) + */ + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); + } /** * Get field object after having set up all necessary values. */ public Field getField() { final String signature = getSignature(); - final int name_index = super.getConstantPool().addUtf8(super.getName()); - final int signature_index = super.getConstantPool().addUtf8(signature); + final int nameIndex = super.getConstantPool().addUtf8(super.getName()); + final int signatureIndex = super.getConstantPool().addUtf8(signature); if (value != null) { checkType(super.getType()); final int index = addConstant(); - addAttribute(new ConstantValue(super.getConstantPool().addUtf8("ConstantValue"), 2, index, - super.getConstantPool().getConstantPool())); // sic + addAttribute(new ConstantValue(super.getConstantPool().addUtf8("ConstantValue"), 2, index, super.getConstantPool().getConstantPool())); // sic } addAnnotationsAsAttribute(super.getConstantPool()); - return new Field(super.getAccessFlags(), name_index, signature_index, getAttributes(), - super.getConstantPool().getConstantPool()); // sic + return new Field(super.getAccessFlags(), nameIndex, signatureIndex, getAttributes(), super.getConstantPool().getConstantPool()); // sic } - private void addAnnotationsAsAttribute(final ConstantPoolGen cp) { - final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); - for (final Attribute attr : attrs) { - addAttribute(attr); - } - } - - - private int addConstant() { - switch (super.getType().getType()) { // sic - case Const.T_INT: - case Const.T_CHAR: - case Const.T_BYTE: - case Const.T_BOOLEAN: - case Const.T_SHORT: - return super.getConstantPool().addInteger(((Integer) value)); - case Const.T_FLOAT: - return super.getConstantPool().addFloat(((Float) value)); - case Const.T_DOUBLE: - return super.getConstantPool().addDouble(((Double) value)); - case Const.T_LONG: - return super.getConstantPool().addLong(((Long) value)); - case Const.T_REFERENCE: - return super.getConstantPool().addString((String) value); - default: - throw new IllegalStateException("Unhandled : " + super.getType().getType()); // sic + public String getInitValue() { + if (value != null) { + return value.toString(); } + return null; } - @Override public String getSignature() { return super.getType().getSignature(); } - private List observers; - - - /** Add observer for this object. + /** + * Return value as defined by given BCELComparator strategy. By default return the hashcode of the field's name XOR + * signature. + * + * @see Object#hashCode() */ - public void addObserver( final FieldObserver o ) { - if (observers == null) { - observers = new ArrayList<>(); - } - observers.add(o); + @Override + public int hashCode() { + return bcelComparator.hashCode(this); } - - /** Remove observer for this object. + /** + * Remove observer for this object. */ - public void removeObserver( final FieldObserver o ) { + public void removeObserver(final FieldObserver o) { if (observers != null) { observers.remove(o); } } + public void setInitValue(final boolean b) { + checkType(Type.BOOLEAN); + if (b) { + value = Integer.valueOf(1); + } + } - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. - */ - public void update() { - if (observers != null) { - for (final FieldObserver observer : observers ) { - observer.notify(this); - } + public void setInitValue(final byte b) { + checkType(Type.BYTE); + if (b != 0) { + value = Integer.valueOf(b); } } + public void setInitValue(final char c) { + checkType(Type.CHAR); + if (c != 0) { + value = Integer.valueOf(c); + } + } - public String getInitValue() { - if (value != null) { - return value.toString(); + public void setInitValue(final double d) { + checkType(Type.DOUBLE); + if (d != 0.0) { + value = Double.valueOf(d); + } + } + + public void setInitValue(final float f) { + checkType(Type.FLOAT); + if (f != 0.0) { + value = Float.valueOf(f); + } + } + + public void setInitValue(final int i) { + checkType(Type.INT); + if (i != 0) { + value = Integer.valueOf(i); + } + } + + public void setInitValue(final long l) { + checkType(Type.LONG); + if (l != 0L) { + value = Long.valueOf(l); + } + } + + public void setInitValue(final short s) { + checkType(Type.SHORT); + if (s != 0) { + value = Integer.valueOf(s); } - return null; } + /** + * Set (optional) initial value of field, otherwise it will be set to null/0/false by the JVM automatically. + */ + public void setInitValue(final String str) { + checkType(ObjectType.getInstance("java.lang.String")); + if (str != null) { + value = str; + } + } + + private void setValue(final int index) { + final ConstantPool cp = super.getConstantPool().getConstantPool(); + final Constant c = cp.getConstant(index); + value = ((ConstantObject) c).getConstantValue(cp); + } /** - * Return string representation close to declaration format, - * `public static final short MAX = 100', e.g.. + * Return string representation close to declaration format, 'public static final short MAX = 100', e.g.. * * @return String representation of field */ @@ -320,7 +321,7 @@ String signature; String access; // Short cuts to constant pool access = Utility.accessToString(super.getAccessFlags()); - access = access.isEmpty() ? "" : (access + " "); + access = access.isEmpty() ? "" : access + " "; signature = super.getType().toString(); name = getName(); final StringBuilder buf = new StringBuilder(32); // CHECKSTYLE IGNORE MagicNumber @@ -332,53 +333,15 @@ return buf.toString(); } - - /** @return deep copy of this field - */ - public FieldGen copy( final ConstantPoolGen cp ) { - final FieldGen fg = (FieldGen) clone(); - fg.setConstantPool(cp); - return fg; - } - - /** - * @return Comparison strategy object + * Call notify() method on all observers. This method is not called automatically whenever the state has changed, but + * has to be called by the user after they have finished editing the object. */ - public static BCELComparator getComparator() { - return bcelComparator; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two FieldGen objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals( final Object obj ) { - return bcelComparator.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the field's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return bcelComparator.hashCode(this); + public void update() { + if (observers != null) { + for (final FieldObserver observer : observers) { + observer.notify(this); + } + } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldGenOrMethodGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -20,6 +20,7 @@ package com.sun.org.apache.bcel.internal.generic; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import com.sun.org.apache.bcel.internal.Const; @@ -27,109 +28,128 @@ import com.sun.org.apache.bcel.internal.classfile.Attribute; /** - * Super class for FieldGen and MethodGen objects, since they have - * some methods in common! + * Super class for FieldGen and MethodGen objects, since they have some methods in common! * * @LastModified: May 2021 */ public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable { - private String name; - private Type type; - private ConstantPoolGen cp; + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected String name; + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected Type type; + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected ConstantPoolGen cp; private final List attributeList = new ArrayList<>(); // @since 6.0 private final List annotationList = new ArrayList<>(); - protected FieldGenOrMethodGen() { } - /** * @since 6.0 */ - protected FieldGenOrMethodGen(final int access_flags) { // TODO could this be package protected? - super(access_flags); + protected FieldGenOrMethodGen(final int accessFlags) { // TODO could this be package protected? + super(accessFlags); } - @Override - public void setType( final Type type ) { // TODO could be package-protected? - if (type.getType() == Const.T_ADDRESS) { - throw new IllegalArgumentException("Type can not be " + type); - } - this.type = type; + protected void addAll(final Attribute[] attrs) { + Collections.addAll(attributeList, attrs); } - - @Override - public Type getType() { - return type; + /** + * @since 6.0 + */ + public void addAnnotationEntry(final AnnotationEntryGen ag) { + annotationList.add(ag); } - - /** @return name of method/field. + /** + * Add an attribute to this method. Currently, the JVM knows about the 'Code', 'ConstantValue', 'Synthetic' and + * 'Exceptions' attributes. Other attributes will be ignored by the JVM but do no harm. + * + * @param a attribute to be added */ - @Override - public String getName() { - return name; + public void addAttribute(final Attribute a) { + attributeList.add(a); } - @Override - public void setName( final String name ) { // TODO could be package-protected? - this.name = name; + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } } - - public ConstantPoolGen getConstantPool() { - return cp; + public AnnotationEntryGen[] getAnnotationEntries() { + return annotationList.toArray(AnnotationEntryGen.EMPTY_ARRAY); } - - public void setConstantPool( final ConstantPoolGen cp ) { // TODO could be package-protected? - this.cp = cp; + /** + * @return all attributes of this method. + */ + public Attribute[] getAttributes() { + return attributeList.toArray(Attribute.EMPTY_ARRAY); } + public ConstantPoolGen getConstantPool() { + return cp; + } /** - * Add an attribute to this method. Currently, the JVM knows about - * the `Code', `ConstantValue', `Synthetic' and `Exceptions' - * attributes. Other attributes will be ignored by the JVM but do no - * harm. - * - * @param a attribute to be added + * @return name of method/field. */ - public void addAttribute( final Attribute a ) { - attributeList.add(a); + @Override + public String getName() { + return name; } /** - * @since 6.0 + * @return signature of method/field. */ - public void addAnnotationEntry(final AnnotationEntryGen ag) - { - annotationList.add(ag); - } + public abstract String getSignature(); + @Override + public Type getType() { + return type; + } /** - * Remove an attribute. + * @since 6.0 */ - public void removeAttribute( final Attribute a ) { - attributeList.remove(a); + public void removeAnnotationEntries() { + annotationList.clear(); } /** * @since 6.0 */ - public void removeAnnotationEntry(final AnnotationEntryGen ag) - { + public void removeAnnotationEntry(final AnnotationEntryGen ag) { annotationList.remove(ag); } + /** + * Remove an attribute. + */ + public void removeAttribute(final Attribute a) { + attributeList.remove(a); + } /** * Remove all attributes. @@ -138,38 +158,20 @@ attributeList.clear(); } - /** - * @since 6.0 - */ - public void removeAnnotationEntries() - { - annotationList.clear(); + public void setConstantPool(final ConstantPoolGen cp) { // TODO could be package-protected? + this.cp = cp; } - - /** - * @return all attributes of this method. - */ - public Attribute[] getAttributes() { - return attributeList.toArray(new Attribute[0]); + @Override + public void setName(final String name) { // TODO could be package-protected? + this.name = name; } - public AnnotationEntryGen[] getAnnotationEntries() { - return annotationList.toArray(new AnnotationEntryGen[0]); - } - - - /** @return signature of method/field. - */ - public abstract String getSignature(); - - @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - throw new Error("Clone Not Supported"); // never happens + public void setType(final Type type) { // TODO could be package-protected? + if (type.getType() == Const.T_ADDRESS) { + throw new IllegalArgumentException("Type can not be " + type); } + this.type = type; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,18 +25,15 @@ /** * Super class for the GET/PUTxxx family of instructions. - * */ public abstract class FieldInstruction extends FieldOrMethod { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ FieldInstruction() { } - /** * @param index to constant pool */ @@ -44,42 +41,40 @@ super(opcode, index); } - /** - * @return mnemonic for instruction with symbolic references resolved + * @return name of referenced field. */ - @Override - public String toString( final ConstantPool cp ) { - return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " - + cp.constantToString(super.getIndex(), com.sun.org.apache.bcel.internal.Const.CONSTANT_Fieldref); + public String getFieldName(final ConstantPoolGen cpg) { + return getName(cpg); } - - /** @return size of field (1 or 2) + /** + * @return size of field (1 or 2) */ - protected int getFieldSize( final ConstantPoolGen cpg ) { + protected int getFieldSize(final ConstantPoolGen cpg) { return Type.size(Type.getTypeSize(getSignature(cpg))); } - - /** @return return type of referenced field + /** + * @return type of field */ - @Override - public Type getType( final ConstantPoolGen cpg ) { - return getFieldType(cpg); + public Type getFieldType(final ConstantPoolGen cpg) { + return Type.getType(getSignature(cpg)); } - - /** @return type of field + /** + * @return return type of referenced field */ - public Type getFieldType( final ConstantPoolGen cpg ) { - return Type.getType(getSignature(cpg)); + @Override + public Type getType(final ConstantPoolGen cpg) { + return getFieldType(cpg); } - - /** @return name of referenced field. + /** + * @return mnemonic for instruction with symbolic references resolved */ - public String getFieldName( final ConstantPoolGen cpg ) { - return getName(cpg); + @Override + public String toString(final ConstantPool cp) { + return com.sun.org.apache.bcel.internal.Const.getOpcodeName(super.getOpcode()) + " " + cp.constantToString(super.getIndex(), com.sun.org.apache.bcel.internal.Const.CONSTANT_Fieldref); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldObserver.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,11 +22,10 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Imnplement this interface if you're interested in changes to a FieldGen object - * and register yourself with addObserver(). - * + * Imnplement this interface if you're interested in changes to a FieldGen object and register yourself with + * addObserver(). */ public interface FieldObserver { - void notify( FieldGen field ); + void notify(FieldGen field); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FieldOrMethod.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,23 +26,20 @@ import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** - * Super class for InvokeInstruction and FieldInstruction, since they have - * some methods in common! - * + * Super class for InvokeInstruction and FieldInstruction, since they have some methods in common! */ public abstract class FieldOrMethod extends CPInstruction implements LoadClass { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ FieldOrMethod() { // no init } - /** * @param index to constant pool */ @@ -50,36 +47,12 @@ super(opcode, index); } - - /** @return signature of referenced method/field. - */ - public String getSignature(final ConstantPoolGen cpg) { - final ConstantPool cp = cpg.getConstantPool(); - final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); - final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); - } - - - /** @return name of referenced method/field. - */ - public String getName(final ConstantPoolGen cpg) { - final ConstantPool cp = cpg.getConstantPool(); - final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); - final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); - return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); - } - - /** * @return name of the referenced class/interface - * @deprecated If the instruction references an array class, - * this method will return "java.lang.Object". - * For code generated by Java 1.5, this answer is - * sometimes wrong (e.g., if the "clone()" method is - * called on an array). A better idea is to use - * the {@link #getReferenceType(ConstantPoolGen)} method, which correctly distinguishes - * between class types and array types. + * @deprecated If the instruction references an array class, this method will return "java.lang.Object". For code + * generated by Java 1.5, this answer is sometimes wrong (e.g., if the "clone()" method is called on an + * array). A better idea is to use the {@link #getReferenceType(ConstantPoolGen)} method, which correctly + * distinguishes between class types and array types. * */ @Deprecated @@ -91,28 +64,50 @@ // Turn array classes into java.lang.Object. return "java.lang.Object"; } - return className.replace('/', '.'); + return Utility.pathToPackage(className); } - - /** @return type of the referenced class/interface - * @deprecated If the instruction references an array class, - * the ObjectType returned will be invalid. Use - * getReferenceType() instead. + /** + * @return type of the referenced class/interface + * @deprecated If the instruction references an array class, the ObjectType returned will be invalid. Use + * getReferenceType() instead. */ @Deprecated public ObjectType getClassType(final ConstantPoolGen cpg) { return ObjectType.getInstance(getClassName(cpg)); } + /** + * Gets the ObjectType of the method return or field. + * + * @return type of the referenced class/interface + * @throws ClassGenException when the field is (or method returns) an array, + */ + @Override + public ObjectType getLoadClassType(final ConstantPoolGen cpg) { + final ReferenceType rt = getReferenceType(cpg); + if (rt instanceof ObjectType) { + return (ObjectType) rt; + } + throw new ClassGenException(rt.getClass().getCanonicalName() + " " + rt.getSignature() + " does not represent an ObjectType"); + } + + /** + * @return name of referenced method/field. + */ + public String getName(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } /** - * Gets the reference type representing the class, interface, - * or array class referenced by the instruction. + * Gets the reference type representing the class, interface, or array class referenced by the instruction. + * * @param cpg the ConstantPoolGen used to create the instruction - * @return an ObjectType (if the referenced class type is a class - * or interface), or an ArrayType (if the referenced class - * type is an array class) + * @return an ObjectType (if the referenced class type is a class or interface), or an ArrayType (if the referenced + * class type is an array class) */ public ReferenceType getReferenceType(final ConstantPoolGen cpg) { final ConstantPool cp = cpg.getConstantPool(); @@ -121,24 +116,17 @@ if (className.startsWith("[")) { return (ArrayType) Type.getType(className); } - className = className.replace('/', '.'); + className = Utility.pathToPackage(className); return ObjectType.getInstance(className); } - /** - * Gets the ObjectType of the method return or field. - * - * @return type of the referenced class/interface - * @throws ClassGenException when the field is (or method returns) an array, + * @return signature of referenced method/field. */ - @Override - public ObjectType getLoadClassType(final ConstantPoolGen cpg) { - final ReferenceType rt = getReferenceType(cpg); - if (rt instanceof ObjectType) { - return (ObjectType) rt; - } - throw new ClassGenException(rt.getClass().getCanonicalName() + " " + - rt.getSignature() + " does not represent an ObjectType"); + public String getSignature(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); + final ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FLOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,38 +23,37 @@ /** * FLOAD - Load float from local variable - *
    Stack ... -> ..., result
    * + *
    + * Stack ... -> ..., result
    + * 
    */ public class FLOAD extends LoadInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ FLOAD() { super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0); } - - /** Load float from local variable + /** + * Load float from local variable + * * @param n index of local variable */ public FLOAD(final int n) { super(com.sun.org.apache.bcel.internal.Const.FLOAD, com.sun.org.apache.bcel.internal.Const.FLOAD_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitFLOAD(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FMUL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * FMUL - Multiply floats - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class FMUL extends ArithmeticInstruction { - /** Multiply floats + /** + * Multiply floats */ public FMUL() { super(com.sun.org.apache.bcel.internal.Const.FMUL); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FNEG.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * FNEG - Negate float - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class FNEG extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.FNEG); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FREM.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * FREM - Remainder of floats - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class FREM extends ArithmeticInstruction { - /** Remainder of floats + /** + * Remainder of floats */ public FREM() { super(com.sun.org.apache.bcel.internal.Const.FREM); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FRETURN.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * FRETURN - Return float from method - *
    Stack: ..., value -> <empty>
    + * FRETURN - Return float from method * + *
    + * Stack: ..., value -> <empty>
    + * 
    */ public class FRETURN extends ReturnInstruction { - /** Return float from method + /** + * Return float from method */ public FRETURN() { super(com.sun.org.apache.bcel.internal.Const.FRETURN); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,38 +23,37 @@ /** * FSTORE - Store float into local variable - *
    Stack: ..., value -> ... 
    * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class FSTORE extends StoreInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ FSTORE() { super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0); } - - /** Store float into local variable + /** + * Store float into local variable + * * @param n index of local variable */ public FSTORE(final int n) { super(com.sun.org.apache.bcel.internal.Const.FSTORE, com.sun.org.apache.bcel.internal.Const.FSTORE_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitFSTORE(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/FSUB.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * FSUB - Substract floats - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class FSUB extends ArithmeticInstruction { - /** Substract floats + /** + * Substract floats */ public FSUB() { super(com.sun.org.apache.bcel.internal.Const.FSUB); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETFIELD.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,51 +25,37 @@ /** * GETFIELD - Fetch field from object - *
    Stack: ..., objectref -> ..., value
    + * + *
    + * Stack: ..., objectref -> ..., value
    + * 
    + * * OR - *
    Stack: ..., objectref -> ..., value.word1, value.word2
    * + *
    + * Stack: ..., objectref -> ..., value.word1, value.word2
    + * 
    */ -public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer, - StackProducer { +public class GETFIELD extends FieldInstruction implements ExceptionThrower, StackConsumer, StackProducer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ GETFIELD() { } - public GETFIELD(final int index) { super(Const.GETFIELD, index); } - - @Override - public int produceStack( final ConstantPoolGen cpg ) { - return getFieldSize(cpg); - } - - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.NULL_POINTER_EXCEPTION, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitStackConsumer(this); v.visitStackProducer(this); @@ -80,4 +66,15 @@ v.visitFieldInstruction(this); v.visitGETFIELD(this); } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + @Override + public int produceStack(final ConstantPoolGen cpg) { + return getFieldSize(cpg); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GETSTATIC.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,49 +26,37 @@ /** * GETSTATIC - Fetch static field from class - *
    Stack: ..., -> ..., value
    + * + *
    + * Stack: ..., -> ..., value
    + * 
    + * * OR - *
    Stack: ..., -> ..., value.word1, value.word2
    * + *
    + * Stack: ..., -> ..., value.word1, value.word2
    + * 
    */ public class GETSTATIC extends FieldInstruction implements PushInstruction, ExceptionThrower { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ GETSTATIC() { } - public GETSTATIC(final int index) { super(Const.GETSTATIC, index); } - - @Override - public int produceStack( final ConstantPoolGen cpg ) { - return getFieldSize(cpg); - } - - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitPushInstruction(this); v.visitExceptionThrower(this); @@ -79,4 +67,14 @@ v.visitFieldInstruction(this); v.visitGETSTATIC(this); } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } + + @Override + public int produceStack(final ConstantPoolGen cpg) { + return getFieldSize(cpg); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GotoInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,19 +23,16 @@ /** * Super class for GOTO - * */ public abstract class GotoInstruction extends BranchInstruction implements UnconditionalBranch { - GotoInstruction(final short opcode, final InstructionHandle target) { - super(opcode, target); - } - - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ GotoInstruction() { } + + GotoInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,77 +26,70 @@ /** * GOTO - Branch always (to relative offset, not absolute address) - * */ public class GOTO extends GotoInstruction implements VariableLengthInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ GOTO() { } - public GOTO(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.GOTO, target); } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitVariableLengthInstruction(this); + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { super.setIndex(getTargetOffset()); - final short _opcode = getOpcode(); - if (_opcode == com.sun.org.apache.bcel.internal.Const.GOTO) { + final short opcode = getOpcode(); + if (opcode == com.sun.org.apache.bcel.internal.Const.GOTO) { super.dump(out); } else { // GOTO_W super.setIndex(getTargetOffset()); - out.writeByte(_opcode); + out.writeByte(opcode); out.writeInt(super.getIndex()); } } - /** - * Called in pass 2 of InstructionList.setPositions() in order to update - * the branch target, that may shift due to variable length instructions. + * Called in pass 2 of InstructionList.setPositions() in order to update the branch target, that may shift due to + * variable length instructions. * * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions + * @param maxOffset the maximum offset that may be caused by these instructions * @return additional offset caused by possible change of this instruction's length */ @Override - protected int updatePosition( final int offset, final int max_offset ) { + protected int updatePosition(final int offset, final int maxOffset) { final int i = getTargetOffset(); // Depending on old position value setPosition(getPosition() + offset); // Position may be shifted by preceding expansions - if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) + if (Math.abs(i) >= Short.MAX_VALUE - maxOffset) { // to large for short (estimate) super.setOpcode(com.sun.org.apache.bcel.internal.Const.GOTO_W); - final short old_length = (short) super.getLength(); + final short oldLength = (short) super.getLength(); super.setLength(5); - return super.getLength() - old_length; + return super.getLength() - oldLength; } return 0; } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitVariableLengthInstruction(this); - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/GOTO_W.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,59 +28,52 @@ /** * GOTO_W - Branch always (to relative offset, not absolute address) - * */ public class GOTO_W extends GotoInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ GOTO_W() { } - public GOTO_W(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.GOTO_W, target); super.setLength(5); } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitUnconditionalBranch(this); + v.visitBranchInstruction(this); + v.visitGotoInstruction(this); + v.visitGOTO_W(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { super.setIndex(getTargetOffset()); out.writeByte(super.getOpcode()); out.writeInt(super.getIndex()); } - /** * Read needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { super.setIndex(bytes.readInt()); super.setLength(5); } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitUnconditionalBranch(this); - v.visitBranchInstruction(this); - v.visitGotoInstruction(this); - v.visitGOTO_W(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2B.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * I2B - Convert int to byte - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class I2B extends ConversionInstruction { - /** Convert int to byte + /** + * Convert int to byte */ public I2B() { super(com.sun.org.apache.bcel.internal.Const.I2B); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2C.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * I2C - Convert int to char - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class I2C extends ConversionInstruction { - /** Convert int to char + /** + * Convert int to char */ public I2C() { super(com.sun.org.apache.bcel.internal.Const.I2C); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2D.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * I2D - Convert int to double - *
    Stack: ..., value -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value -> ..., result.word1, result.word2
    + * 
    */ public class I2D extends ConversionInstruction { - /** Convert int to double + /** + * Convert int to double */ public I2D() { super(com.sun.org.apache.bcel.internal.Const.I2D); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2F.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * I2F - Convert int to float - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class I2F extends ConversionInstruction { - /** Convert int to float + /** + * Convert int to float */ public I2F() { super(com.sun.org.apache.bcel.internal.Const.I2F); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2L.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * I2L - Convert int to long - *
    Stack: ..., value -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value -> ..., result.word1, result.word2
    + * 
    */ public class I2L extends ConversionInstruction { - /** Convert int to long + /** + * Convert int to long */ public I2L() { super(com.sun.org.apache.bcel.internal.Const.I2L); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/I2S.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * I2S - Convert int to short - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class I2S extends ConversionInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.I2S); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IADD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * IADD - Add ints - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class IADD extends ArithmeticInstruction { - /** Add ints + /** + * Add ints */ public IADD() { super(com.sun.org.apache.bcel.internal.Const.IADD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * IALOAD - Load int from array - *
    Stack: ..., arrayref, index -> ..., value
    * + *
    + * Stack: ..., arrayref, index -> ..., value
    + * 
    */ public class IALOAD extends ArrayInstruction implements StackProducer { @@ -35,17 +37,14 @@ super(com.sun.org.apache.bcel.internal.Const.IALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IAND.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * IAND - Bitwise AND int - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class IAND extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.IAND); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,9 +22,11 @@ package com.sun.org.apache.bcel.internal.generic; /** - * IASTORE - Store into int array - *
    Stack: ..., arrayref, index, value -> ...
    + * IASTORE - Store into int array * + *
    + * Stack: ..., arrayref, index, value -> ...
    + * 
    */ public class IASTORE extends ArrayInstruction implements StackConsumer { @@ -35,17 +37,14 @@ super(com.sun.org.apache.bcel.internal.Const.IASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ICONST.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,61 +22,56 @@ /** * ICONST - Push value between -1, ..., 5, other values cause an exception * - *
    Stack: ... -> ..., 
    + *
    + * Stack: ... -> ...,
    + * 
    * */ public class ICONST extends Instruction implements ConstantPushInstruction { - private int value; - + private final int value; /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ICONST() { + this(0); } - public ICONST(final int i) { super(com.sun.org.apache.bcel.internal.Const.ICONST_0, (short) 1); - if ((i >= -1) && (i <= 5)) { - super.setOpcode((short) (com.sun.org.apache.bcel.internal.Const.ICONST_0 + i)); // Even works for i == -1 - } else { + if (i < -1 || i > 5) { throw new ClassGenException("ICONST can be used only for value between -1 and 5: " + i); } + super.setOpcode((short) (com.sun.org.apache.bcel.internal.Const.ICONST_0 + i)); // Even works for i == -1 value = i; } - - @Override - public Number getValue() { - return Integer.valueOf(value); - } - - - /** @return Type.INT - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.INT; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitPushInstruction(this); v.visitStackProducer(this); v.visitTypedInstruction(this); v.visitConstantPushInstruction(this); v.visitICONST(this); } + + /** + * @return Type.INT + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.INT; + } + + @Override + public Number getValue() { + return Integer.valueOf(value); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IDIV.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,39 +24,29 @@ /** * IDIV - Divide ints - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    * @LastModified: Jan 2020 */ public class IDIV extends ArithmeticInstruction implements ExceptionThrower { - /** Divide ints + /** + * Divide ints */ public IDIV() { super(com.sun.org.apache.bcel.internal.Const.IDIV); } - - /** @return exceptions this instruction may cause - */ - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.ARITHMETIC_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackProducer(this); @@ -64,4 +54,12 @@ v.visitArithmeticInstruction(this); v.visitIDIV(this); } + + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.ARITHMETIC_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPEQ.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ACMPEQ - Branch if reference comparison succeeds * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ACMPEQ extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ACMPEQ() { } - public IF_ACMPEQ(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ACMPEQ, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ACMPNE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ACMPEQ(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPNE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ACMPNE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ACMPNE - Branch if reference comparison doesn't succeed * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ACMPNE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ACMPNE() { } - public IF_ACMPNE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ACMPNE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ACMPEQ(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ACMPNE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ACMPEQ(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFEQ.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFEQ - Branch if int comparison with zero succeeds * - *
    Stack: ..., value -> ...
    - * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class IFEQ extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFEQ() { } - public IFEQ(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFEQ, target); } - - /** - * @return negation of instruction, e.g. IFEQ.negate() == IFNE - */ - @Override - public IfInstruction negate() { - return new IFNE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFEQ(this); } + + /** + * @return negation of instruction, e.g. IFEQ.negate() == IFNE + */ + @Override + public IfInstruction negate() { + return new IFNE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFGE - Branch if int comparison with zero succeeds * - *
    Stack: ..., value -> ...
    - * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class IFGE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFGE() { } - public IFGE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFGE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFLT(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFGE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLT(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFGT.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFGT - Branch if int comparison with zero succeeds * - *
    Stack: ..., value -> ...
    - * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class IFGT extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFGT() { } - public IFGT(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFGT, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFLE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFGT(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFLE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPEQ.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ICMPEQ - Branch if int comparison succeeds * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ICMPEQ extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ICMPEQ() { } - public IF_ICMPEQ(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ICMPEQ, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ICMPNE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ICMPEQ(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPNE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ICMPGE - Branch if int comparison succeeds * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ICMPGE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ICMPGE() { } - public IF_ICMPGE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ICMPGE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ICMPLT(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ICMPGE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLT(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPGT.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ICMPGT - Branch if int comparison succeeds * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ICMPGT extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ICMPGT() { } - public IF_ICMPGT(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ICMPGT, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ICMPLE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ICMPGT(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPLE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ICMPLE - Branch if int comparison succeeds * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ICMPLE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ICMPLE() { } - public IF_ICMPLE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ICMPLE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ICMPGT(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ICMPLE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGT(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPLT.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ICMPLT - Branch if int comparison succeeds * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ICMPLT extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ICMPLT() { } - public IF_ICMPLT(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ICMPLT, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ICMPGE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ICMPLT(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPGE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IF_ICMPNE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IF_ICMPNE - Branch if int comparison doesn't succeed * - *
    Stack: ..., value1, value2 -> ...
    - * + *
    + * Stack: ..., value1, value2 -> ...
    + * 
    */ public class IF_ICMPNE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IF_ICMPNE() { } - public IF_ICMPNE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IF_ICMPNE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IF_ICMPEQ(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIF_ICMPNE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IF_ICMPEQ(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IfInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,18 +23,15 @@ /** * Super class for the IFxxx family of instructions. - * */ public abstract class IfInstruction extends BranchInstruction implements StackConsumer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IfInstruction() { } - /** * @param opcode opcode of instruction * @param target Target instruction to branch to @@ -43,7 +40,6 @@ super(opcode, target); } - /** * @return negation of instruction, e.g. IFEQ.negate() == IFNE */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFLE - Branch if int comparison with zero succeeds * - *
    Stack: ..., value -> ...
    - * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class IFLE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFLE() { } - public IFLE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFLE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFGT(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFLE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGT(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFLT.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFLT - Branch if int comparison with zero succeeds * - *
    Stack: ..., value -> ...
    - * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class IFLT extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFLT() { } - public IFLT(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFLT, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFGE(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFLT(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFGE(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNE.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFNE - Branch if int comparison with zero succeeds * - *
    Stack: ..., value -> ...
    - * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class IFNE extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFNE() { } - public IFNE(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFNE, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFEQ(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFNE(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFEQ(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNONNULL.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFNONNULL - Branch if reference is not null * - *
    Stack: ..., reference -> ...
    - * + *
    + * Stack: ..., reference -> ...
    + * 
    */ public class IFNONNULL extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFNONNULL() { } - public IFNONNULL(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFNONNULL, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFNULL(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFNONNULL(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNULL(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IFNULL.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,46 +24,41 @@ /** * IFNULL - Branch if reference is not null * - *
    Stack: ..., reference -> ...
    - * + *
    + * Stack: ..., reference -> ...
    + * 
    */ public class IFNULL extends IfInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IFNULL() { } - public IFNULL(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.IFNULL, target); } - - /** - * @return negation of instruction - */ - @Override - public IfInstruction negate() { - return new IFNONNULL(super.getTarget()); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitBranchInstruction(this); v.visitIfInstruction(this); v.visitIFNULL(this); } + + /** + * @return negation of instruction + */ + @Override + public IfInstruction negate() { + return new IFNONNULL(super.getTarget()); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IINC.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,47 +24,56 @@ import java.io.DataOutputStream; import java.io.IOException; +import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.util.ByteSequence; /** * IINC - Increment local variable by constant - * */ public class IINC extends LocalVariableInstruction { private boolean wide; private int c; - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ IINC() { } - /** * @param n index of local variable * @param c increment factor */ public IINC(final int n, final int c) { - super(); // Default behavior of LocalVariableInstruction causes error - super.setOpcode(com.sun.org.apache.bcel.internal.Const.IINC); + // Default behavior of LocalVariableInstruction causes error + super.setOpcode(Const.IINC); super.setLength((short) 3); setIndex(n); // May set wide as side effect setIncrement(c); } + /** + * Calls corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitLocalVariableInstruction(this); + v.visitIINC(this); + } /** - * Dump instruction as byte code to stream out. + * Dumps instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { if (wide) { - out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); + out.writeByte(Const.WIDE); } out.writeByte(super.getOpcode()); if (wide) { @@ -76,27 +85,26 @@ } } - - private void setWide() { - wide = super.getIndex() > com.sun.org.apache.bcel.internal.Const.MAX_BYTE; - if (c > 0) { - wide = wide || (c > Byte.MAX_VALUE); - } else { - wide = wide || (c < Byte.MIN_VALUE); - } - if (wide) { - super.setLength(6); // wide byte included - } else { - super.setLength(3); - } + /** + * @return increment factor + */ + public final int getIncrement() { + return c; } + /** + * @return int type + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.INT; + } /** - * Read needed data (e.g. index) from file. + * Reads needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { this.wide = wide; if (wide) { super.setLength(6); @@ -109,21 +117,19 @@ } } - /** - * @return mnemonic for instruction + * Sets increment factor. */ - @Override - public String toString( final boolean verbose ) { - return super.toString(verbose) + " " + c; + public final void setIncrement(final int c) { + this.c = c; + setWide(); } - /** - * Set index of local variable. + * Sets index of local variable. */ @Override - public final void setIndex( final int n ) { + public final void setIndex(final int n) { if (n < 0) { throw new ClassGenException("Negative index value: " + n); } @@ -131,43 +137,27 @@ setWide(); } - - /** - * @return increment factor - */ - public final int getIncrement() { - return c; - } - - - /** - * Set increment factor. - */ - public final void setIncrement( final int c ) { - this.c = c; - setWide(); - } - - - /** @return int type - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.INT; + private void setWide() { + wide = super.getIndex() > Const.MAX_BYTE; + if (c > 0) { + wide = wide || c > Byte.MAX_VALUE; + } else { + wide = wide || c < Byte.MIN_VALUE; + } + if (wide) { + super.setLength(6); // wide byte included + } else { + super.setLength(3); + } } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Returns mnemonic for instruction. * - * @param v Visitor object + * @return mnemonic for instruction. */ @Override - public void accept( final Visitor v ) { - v.visitLocalVariableInstruction(this); - v.visitIINC(this); + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + c; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ILOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,38 +23,37 @@ /** * ILOAD - Load int from local variable onto stack - *
    Stack: ... -> ..., result
    * + *
    + * Stack: ... -> ..., result
    + * 
    */ public class ILOAD extends LoadInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ILOAD() { super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0); } - - /** Load int from local variable + /** + * Load int from local variable + * * @param n index of local variable */ public ILOAD(final int n) { super(com.sun.org.apache.bcel.internal.Const.ILOAD, com.sun.org.apache.bcel.internal.Const.ILOAD_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitILOAD(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP1.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,7 +23,6 @@ /** * IMPDEP1 - Implementation dependent - * */ public class IMPDEP1 extends Instruction { @@ -31,17 +30,14 @@ super(com.sun.org.apache.bcel.internal.Const.IMPDEP1, (short) 1); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitIMPDEP1(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMPDEP2.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,7 +23,6 @@ /** * IMPDEP2 - Implementation dependent - * */ public class IMPDEP2 extends Instruction { @@ -31,17 +30,14 @@ super(com.sun.org.apache.bcel.internal.Const.IMPDEP2, (short) 1); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitIMPDEP2(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IMUL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * IMUL - Multiply ints - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class IMUL extends ArithmeticInstruction { - /** Multiply ints + /** + * Multiply ints */ public IMUL() { super(com.sun.org.apache.bcel.internal.Const.IMUL); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IndexedInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,14 +22,11 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denote entity that refers to an index, e.g. local variable instructions, - * RET, CPInstruction, etc. - * + * Denote entity that refers to an index, e.g. local variable instructions, RET, CPInstruction, etc. */ public interface IndexedInstruction { int getIndex(); - - void setIndex( int index ); + void setIndex(int index); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INEG.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * INEG - Negate int - *
    Stack: ..., value -> ..., result
    * + *
    + * Stack: ..., value -> ..., result
    + * 
    */ public class INEG extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.INEG); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INSTANCEOF.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,51 +25,31 @@ /** * INSTANCEOF - Determine if object is of given type - *
    Stack: ..., objectref -> ..., result
    * + *
    + * Stack: ..., objectref -> ..., result
    + * 
    */ -public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower, - StackProducer, StackConsumer { +public class INSTANCEOF extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, StackConsumer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ INSTANCEOF() { } - public INSTANCEOF(final int index) { super(com.sun.org.apache.bcel.internal.Const.INSTANCEOF, index); } - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION); - } - - - @Override - public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { - Type t = getType(cpg); - if (t instanceof ArrayType) { - t = ((ArrayType) t).getBasicType(); - } - return (t instanceof ObjectType) ? (ObjectType) t : null; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLoadClass(this); v.visitExceptionThrower(this); v.visitStackProducer(this); @@ -78,4 +58,18 @@ v.visitCPInstruction(this); v.visitINSTANCEOF(this); } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION); + } + + @Override + public ObjectType getLoadClassType(final ConstantPoolGen cpg) { + Type t = getType(cpg); + if (t instanceof ArrayType) { + t = ((ArrayType) t).getBasicType(); + } + return t instanceof ObjectType ? (ObjectType) t : null; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionComparator.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,15 +22,12 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Equality of instructions isn't clearly to be defined. You might - * wish, for example, to compare whether instructions have the same - * meaning. E.g., whether two INVOKEVIRTUALs describe the same - * call. + * Equality of instructions isn't clearly to be defined. You might wish, for example, to compare whether instructions + * have the same meaning. E.g., whether two INVOKEVIRTUALs describe the same call. *

    - * The DEFAULT comparator however, considers two instructions - * to be equal if they have same opcode and point to the same indexes - * (if any) in the constant pool or the same local variable index. Branch - * instructions must have the same target. + * The DEFAULT comparator however, considers two instructions to be equal if they have same opcode and point to the same + * indexes (if any) in the constant pool or the same local variable index. Branch instructions must have the same + * target. *

    * * @see Instruction @@ -40,25 +37,24 @@ InstructionComparator DEFAULT = (i1, i2) -> { if (i1.getOpcode() == i2.getOpcode()) { if (i1 instanceof BranchInstruction) { - // BIs are never equal to make targeters work correctly (BCEL-195) + // BIs are never equal to make targeters work correctly (BCEL-195) return false; // } else if (i1 == i2) { TODO consider adding this shortcut // return true; // this must be AFTER the BI test - } else if (i1 instanceof ConstantPushInstruction) { - return ((ConstantPushInstruction) i1).getValue().equals( - ((ConstantPushInstruction) i2).getValue()); - } else if (i1 instanceof IndexedInstruction) { - return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2) - .getIndex(); - } else if (i1 instanceof NEWARRAY) { + } + if (i1 instanceof ConstantPushInstruction) { + return ((ConstantPushInstruction) i1).getValue().equals(((ConstantPushInstruction) i2).getValue()); + } + if (i1 instanceof IndexedInstruction) { + return ((IndexedInstruction) i1).getIndex() == ((IndexedInstruction) i2).getIndex(); + } + if (i1 instanceof NEWARRAY) { return ((NEWARRAY) i1).getTypecode() == ((NEWARRAY) i2).getTypecode(); - } else { - return true; } + return true; } return false; }; - - boolean equals( Instruction i1, Instruction i2 ); + boolean equals(Instruction i1, Instruction i2); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionConst.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,28 +24,24 @@ import com.sun.org.apache.bcel.internal.Const; /** - * This interface contains shareable instruction objects. - * - * In order to save memory you can use some instructions multiply, - * since they have an immutable state and are directly derived from - * Instruction. I.e. they have no instance fields that could be - * changed. Since some of these instructions like ICONST_0 occur - * very frequently this can save a lot of time and space. This - * feature is an adaptation of the FlyWeight design pattern, we - * just use an array instead of a factory. - * - * The Instructions can also accessed directly under their names, so - * it's possible to write il.append(Instruction.ICONST_0); - * + * Contains shareable instruction objects. + *

    + * In order to save memory you can use some instructions multiply, since they have an immutable state and are directly + * derived from Instruction. I.e. they have no instance fields that could be changed. Since some of these instructions + * like ICONST_0 occur very frequently this can save a lot of time and space. This feature is an adaptation of the + * FlyWeight design pattern, we just use an array instead of a factory. + *

    + *

    + * The Instructions can also accessed directly under their names, so it's possible to write + * il.append(Instruction.ICONST_0); + *

    */ public final class InstructionConst { /** - * Predefined instruction objects - */ - /* - * NOTE these are not currently immutable, because Instruction - * has mutable protected fields opcode and length. + * Predefined instruction objects. + * + * NOTE these are not currently immutable, because Instruction has mutable protected fields opcode and length. */ public static final Instruction NOP = new NOP(); public static final Instruction ACONST_NULL = new ACONST_NULL(); @@ -155,8 +151,9 @@ public static final Instruction MONITORENTER = new MONITORENTER(); public static final Instruction MONITOREXIT = new MONITOREXIT(); - /** You can use these constants in multiple places safely, if you can guarantee - * that you will never alter their internal values, e.g. call setIndex(). + /** + * You can use these constants in multiple places safely, if you can guarantee that you will never alter their internal + * values, e.g. call setIndex(). */ public static final LocalVariableInstruction THIS = new ALOAD(0); public static final LocalVariableInstruction ALOAD_0 = THIS; @@ -172,10 +169,10 @@ public static final LocalVariableInstruction ISTORE_1 = new ISTORE(1); public static final LocalVariableInstruction ISTORE_2 = new ISTORE(2); - /** Get object via its opcode, for immutable instructions like - * branch instructions entries are set to null. + /** + * Get object via its opcode, for immutable instructions like branch instructions entries are set to null. */ - private static final Instruction[] INSTRUCTIONS = new Instruction[256]; + static final Instruction[] INSTRUCTIONS = new Instruction[256]; static { INSTRUCTIONS[Const.NOP] = NOP; @@ -287,14 +284,16 @@ INSTRUCTIONS[Const.MONITOREXIT] = MONITOREXIT; } - private InstructionConst() { } // non-instantiable - /** * Gets the Instruction. + * * @param index the index, e.g. {@link Const#RETURN} * @return the entry from the private INSTRUCTIONS table */ public static Instruction getInstruction(final int index) { return INSTRUCTIONS[index]; } + + private InstructionConst() { + } // non-instantiable } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionFactory.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,672 +22,673 @@ import com.sun.org.apache.bcel.internal.Const; /** - * Instances of this class may be used, e.g., to generate typed - * versions of instructions. Its main purpose is to be used as the - * byte code generating backend of a compiler. You can subclass it to - * add your own create methods. + * Instances of this class may be used, e.g., to generate typed versions of instructions. Its main purpose is to be used + * as the byte code generating backend of a compiler. You can subclass it to add your own create methods. *

    - * Note: The static createXXX methods return singleton instances - * from the {@link InstructionConst} class. + * Note: The static createXXX methods return singleton instances from the {@link InstructionConst} class. + *

    * * @see Const * @see InstructionConst - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public class InstructionFactory { - // N.N. These must agree with the order of Constants.T_CHAR through T_LONG - private static final String[] short_names = { - "C", "F", "D", "B", "S", "I", "L" - }; + private static class MethodObject { - private ClassGen cg; - private ConstantPoolGen cp; + final Type[] argTypes; + final Type resultType; + final String className; + final String name; - public InstructionFactory(final ClassGen cg, final ConstantPoolGen cp) { - this.cg = cg; - this.cp = cp; + MethodObject(final String c, final String n, final Type r, final Type[] a) { + this.className = c; + this.name = n; + this.resultType = r; + this.argTypes = a; + } } + private static final String APPEND = "append"; - /** Initialize with ClassGen object - */ - public InstructionFactory(final ClassGen cg) { - this(cg, cg.getConstantPool()); - } - + private static final String FQCN_STRING_BUFFER = "java.lang.StringBuffer"; - /** Initialize just with ConstantPoolGen object - */ - public InstructionFactory(final ConstantPoolGen cp) { - this(null, cp); - } + // N.N. These must agree with the order of Constants.T_CHAR through T_LONG + private static final String[] shortNames = {"C", "F", "D", "B", "S", "I", "L"}; - - /** Create an invoke instruction. (Except for invokedynamic.) - * - * @param class_name name of the called class - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, - * or INVOKESPECIAL - * @see Const - */ - public InvokeInstruction createInvoke( final String class_name, final String name, - final Type ret_type, final Type[] arg_types, final short kind ) { - return createInvoke(class_name, name, ret_type, arg_types, kind, kind == Const.INVOKEINTERFACE); - } + private static final MethodObject[] appendMethodObjects = { + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.STRING }), + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.OBJECT }), null, null, // indices 2, 3 + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.BOOLEAN }), + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.CHAR }), + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.FLOAT }), + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.DOUBLE }), + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.INT }), + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.INT }), // No append(byte) + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.INT }), // No append(short) + new MethodObject(FQCN_STRING_BUFFER, APPEND, Type.STRINGBUFFER, new Type[] { Type.LONG })}; /** - * Creates an invoke instruction. (Except for invokedynamic.) - * - * @param class_name name of the called class - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @param kind how to invoke: INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL - * @param use_interface force use of InterfaceMethodref - * @return A new InvokeInstruction. - * @since 6.5.0 + * @param type type of elements of array, i.e., array.getElementType() */ - public InvokeInstruction createInvoke( final String class_name, final String name, final Type ret_type, - final Type[] arg_types, final short kind, final boolean use_interface) { - if (kind != Const.INVOKESPECIAL && kind != Const.INVOKEVIRTUAL && kind != Const.INVOKESTATIC - && kind != Const.INVOKEINTERFACE && kind != Const.INVOKEDYNAMIC) { - throw new IllegalArgumentException("Unknown invoke kind: " + kind); - } - int index; - int nargs = 0; - final String signature = Type.getMethodSignature(ret_type, arg_types); - for (final Type arg_type : arg_types) { - nargs += arg_type.getSize(); - } - if (use_interface) { - index = cp.addInterfaceMethodref(class_name, name, signature); - } else { - index = cp.addMethodref(class_name, name, signature); - } - switch (kind) { - case Const.INVOKESPECIAL: - return new INVOKESPECIAL(index); - case Const.INVOKEVIRTUAL: - return new INVOKEVIRTUAL(index); - case Const.INVOKESTATIC: - return new INVOKESTATIC(index); - case Const.INVOKEINTERFACE: - return new INVOKEINTERFACE(index, nargs + 1); - case Const.INVOKEDYNAMIC: - return new INVOKEDYNAMIC(index); + public static ArrayInstruction createArrayLoad(final Type type) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_BYTE: + return InstructionConst.BALOAD; + case Const.T_CHAR: + return InstructionConst.CALOAD; + case Const.T_SHORT: + return InstructionConst.SALOAD; + case Const.T_INT: + return InstructionConst.IALOAD; + case Const.T_FLOAT: + return InstructionConst.FALOAD; + case Const.T_DOUBLE: + return InstructionConst.DALOAD; + case Const.T_LONG: + return InstructionConst.LALOAD; + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.AALOAD; default: - // Can't happen - throw new IllegalStateException("Unknown invoke kind: " + kind); + throw new IllegalArgumentException("Invalid type " + type); } } - /** Create an invokedynamic instruction. - * - * @param bootstrap_index index into the bootstrap_methods array - * @param name name of the called method - * @param ret_type return type of method - * @param arg_types argument types of method - * @see Constants - */ -/* - * createInvokeDynamic only needed if instrumention code wants to generate - * a new invokedynamic instruction. I don't think we need. (markro) - * - public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type, - Type[] arg_types) { - int index; - int nargs = 0; - String signature = Type.getMethodSignature(ret_type, arg_types); - for (int i = 0; i < arg_types.length; i++) { - nargs += arg_types[i].getSize(); - } - // UNDONE - needs to be added to ConstantPoolGen - //index = cp.addInvokeDynamic(bootstrap_index, name, signature); - index = 0; - return new INVOKEDYNAMIC(index); - } - */ - - /** Create a call to the most popular System.out.println() method. - * - * @param s the string to print - */ - public InstructionList createPrintln( final String s ) { - final InstructionList il = new InstructionList(); - final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;"); - final int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V"); - il.append(new GETSTATIC(out)); - il.append(new PUSH(cp, s)); - il.append(new INVOKEVIRTUAL(println)); - return il; - } - - - /** Uses PUSH to push a constant value onto the stack. - * @param value must be of type Number, Boolean, Character or String + /** + * @param type type of elements of array, i.e., array.getElementType() */ - public Instruction createConstant( final Object value ) { - PUSH push; - if (value instanceof Number) { - push = new PUSH(cp, (Number) value); - } else if (value instanceof String) { - push = new PUSH(cp, (String) value); - } else if (value instanceof Boolean) { - push = new PUSH(cp, (Boolean) value); - } else if (value instanceof Character) { - push = new PUSH(cp, (Character) value); - } else { - throw new ClassGenException("Illegal type: " + value.getClass()); + public static ArrayInstruction createArrayStore(final Type type) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_BYTE: + return InstructionConst.BASTORE; + case Const.T_CHAR: + return InstructionConst.CASTORE; + case Const.T_SHORT: + return InstructionConst.SASTORE; + case Const.T_INT: + return InstructionConst.IASTORE; + case Const.T_FLOAT: + return InstructionConst.FASTORE; + case Const.T_DOUBLE: + return InstructionConst.DASTORE; + case Const.T_LONG: + return InstructionConst.LASTORE; + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.AASTORE; + default: + throw new IllegalArgumentException("Invalid type " + type); } - return push.getInstruction(); } - private static class MethodObject { - - final Type[] arg_types; - final Type result_type; - final String class_name; - final String name; - - - MethodObject(final String c, final String n, final Type r, final Type[] a) { - class_name = c; - name = n; - result_type = r; - arg_types = a; + private static ArithmeticInstruction createBinaryDoubleOp(final char op) { + switch (op) { + case '-': + return InstructionConst.DSUB; + case '+': + return InstructionConst.DADD; + case '*': + return InstructionConst.DMUL; + case '/': + return InstructionConst.DDIV; + case '%': + return InstructionConst.DREM; + default: + throw new IllegalArgumentException("Invalid operand " + op); } } - - private InvokeInstruction createInvoke( final MethodObject m, final short kind ) { - return createInvoke(m.class_name, m.name, m.result_type, m.arg_types, kind); - } - - private static final MethodObject[] append_mos = { - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.STRING - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.OBJECT - }), - null, - null, // indices 2, 3 - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.BOOLEAN - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.CHAR - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.FLOAT - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.DOUBLE - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.INT - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(byte) - new Type[] { - Type.INT - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, // No append(short) - new Type[] { - Type.INT - }), - new MethodObject("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] { - Type.LONG - }) - }; - - - private static boolean isString( final Type type ) { - return (type instanceof ObjectType) && - ((ObjectType) type).getClassName().equals("java.lang.String"); + private static ArithmeticInstruction createBinaryFloatOp(final char op) { + switch (op) { + case '-': + return InstructionConst.FSUB; + case '+': + return InstructionConst.FADD; + case '*': + return InstructionConst.FMUL; + case '/': + return InstructionConst.FDIV; + case '%': + return InstructionConst.FREM; + default: + throw new IllegalArgumentException("Invalid operand " + op); + } } - - public Instruction createAppend( final Type type ) { - final byte t = type.getType(); - if (isString(type)) { - return createInvoke(append_mos[0], Const.INVOKEVIRTUAL); - } - switch (t) { - case Const.T_BOOLEAN: - case Const.T_CHAR: - case Const.T_FLOAT: - case Const.T_DOUBLE: - case Const.T_BYTE: - case Const.T_SHORT: - case Const.T_INT: - case Const.T_LONG: - return createInvoke(append_mos[t], Const.INVOKEVIRTUAL); - case Const.T_ARRAY: - case Const.T_OBJECT: - return createInvoke(append_mos[1], Const.INVOKEVIRTUAL); - default: - throw new IllegalArgumentException("No append for this type? " + type); + private static ArithmeticInstruction createBinaryIntOp(final char first, final String op) { + switch (first) { + case '-': + return InstructionConst.ISUB; + case '+': + return InstructionConst.IADD; + case '%': + return InstructionConst.IREM; + case '*': + return InstructionConst.IMUL; + case '/': + return InstructionConst.IDIV; + case '&': + return InstructionConst.IAND; + case '|': + return InstructionConst.IOR; + case '^': + return InstructionConst.IXOR; + case '<': + return InstructionConst.ISHL; + case '>': + return op.equals(">>>") ? InstructionConst.IUSHR : InstructionConst.ISHR; + default: + throw new IllegalArgumentException("Invalid operand " + op); } } - - /** Create a field instruction. + /** + * Create an invokedynamic instruction. * - * @param class_name name of the accessed class - * @param name name of the referenced field - * @param type type of field - * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC + * @param bootstrap_index index into the bootstrap_methods array + * @param name name of the called method + * @param ret_type return type of method + * @param argTypes argument types of method * @see Const */ - public FieldInstruction createFieldAccess( final String class_name, - final String name, final Type type, final short kind ) { - int index; - final String signature = type.getSignature(); - index = cp.addFieldref(class_name, name, signature); - switch (kind) { - case Const.GETFIELD: - return new GETFIELD(index); - case Const.PUTFIELD: - return new PUTFIELD(index); - case Const.GETSTATIC: - return new GETSTATIC(index); - case Const.PUTSTATIC: - return new PUTSTATIC(index); - default: - throw new IllegalArgumentException("Unknown getfield kind:" + kind); - } - } - - /** Create reference to `this' - */ - public static Instruction createThis() { - return new ALOAD(0); - } - - - /** Create typed return + /* + * createInvokeDynamic only needed if instrumentation code wants to generate a new invokedynamic instruction. I don't + * think we need. + * + * public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type, Type[] argTypes) { + * int index; int nargs = 0; String signature = Type.getMethodSignature(ret_type, argTypes); for (int i = 0; i < + * argTypes.length; i++) { nargs += argTypes[i].getSize(); } // UNDONE - needs to be added to ConstantPoolGen //index + * = cp.addInvokeDynamic(bootstrap_index, name, signature); index = 0; return new INVOKEDYNAMIC(index); } */ - public static ReturnInstruction createReturn( final Type type ) { - switch (type.getType()) { - case Const.T_ARRAY: - case Const.T_OBJECT: - return InstructionConst.ARETURN; - case Const.T_INT: - case Const.T_SHORT: - case Const.T_BOOLEAN: - case Const.T_CHAR: - case Const.T_BYTE: - return InstructionConst.IRETURN; - case Const.T_FLOAT: - return InstructionConst.FRETURN; - case Const.T_DOUBLE: - return InstructionConst.DRETURN; - case Const.T_LONG: - return InstructionConst.LRETURN; - case Const.T_VOID: - return InstructionConst.RETURN; - default: - throw new IllegalArgumentException("Invalid type: " + type); - } - } - - private static ArithmeticInstruction createBinaryIntOp( final char first, final String op ) { - switch (first) { - case '-': - return InstructionConst.ISUB; - case '+': - return InstructionConst.IADD; - case '%': - return InstructionConst.IREM; - case '*': - return InstructionConst.IMUL; - case '/': - return InstructionConst.IDIV; - case '&': - return InstructionConst.IAND; - case '|': - return InstructionConst.IOR; - case '^': - return InstructionConst.IXOR; - case '<': - return InstructionConst.ISHL; - case '>': - return op.equals(">>>") ? InstructionConst.IUSHR : InstructionConst.ISHR; - default: - throw new IllegalArgumentException("Invalid operand " + op); - } - } - - - private static ArithmeticInstruction createBinaryLongOp( final char first, final String op ) { + private static ArithmeticInstruction createBinaryLongOp(final char first, final String op) { switch (first) { - case '-': - return InstructionConst.LSUB; - case '+': - return InstructionConst.LADD; - case '%': - return InstructionConst.LREM; - case '*': - return InstructionConst.LMUL; - case '/': - return InstructionConst.LDIV; - case '&': - return InstructionConst.LAND; - case '|': - return InstructionConst.LOR; - case '^': - return InstructionConst.LXOR; - case '<': - return InstructionConst.LSHL; - case '>': - return op.equals(">>>") ? InstructionConst.LUSHR : InstructionConst.LSHR; - default: - throw new IllegalArgumentException("Invalid operand " + op); - } - } - - - private static ArithmeticInstruction createBinaryFloatOp( final char op ) { - switch (op) { - case '-': - return InstructionConst.FSUB; - case '+': - return InstructionConst.FADD; - case '*': - return InstructionConst.FMUL; - case '/': - return InstructionConst.FDIV; - case '%': - return InstructionConst.FREM; - default: - throw new IllegalArgumentException("Invalid operand " + op); - } - } - - - private static ArithmeticInstruction createBinaryDoubleOp( final char op ) { - switch (op) { - case '-': - return InstructionConst.DSUB; - case '+': - return InstructionConst.DADD; - case '*': - return InstructionConst.DMUL; - case '/': - return InstructionConst.DDIV; - case '%': - return InstructionConst.DREM; - default: - throw new IllegalArgumentException("Invalid operand " + op); + case '-': + return InstructionConst.LSUB; + case '+': + return InstructionConst.LADD; + case '%': + return InstructionConst.LREM; + case '*': + return InstructionConst.LMUL; + case '/': + return InstructionConst.LDIV; + case '&': + return InstructionConst.LAND; + case '|': + return InstructionConst.LOR; + case '^': + return InstructionConst.LXOR; + case '<': + return InstructionConst.LSHL; + case '>': + return op.equals(">>>") ? InstructionConst.LUSHR : InstructionConst.LSHR; + default: + throw new IllegalArgumentException("Invalid operand " + op); } } - /** * Create binary operation for simple basic types, such as int and float. * * @param op operation, such as "+", "*", "<<", etc. */ - public static ArithmeticInstruction createBinaryOperation( final String op, final Type type ) { + public static ArithmeticInstruction createBinaryOperation(final String op, final Type type) { final char first = op.charAt(0); switch (type.getType()) { - case Const.T_BYTE: - case Const.T_SHORT: - case Const.T_INT: - case Const.T_CHAR: - return createBinaryIntOp(first, op); - case Const.T_LONG: - return createBinaryLongOp(first, op); - case Const.T_FLOAT: - return createBinaryFloatOp(first); - case Const.T_DOUBLE: - return createBinaryDoubleOp(first); - default: - throw new IllegalArgumentException("Invalid type " + type); + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + case Const.T_CHAR: + return createBinaryIntOp(first, op); + case Const.T_LONG: + return createBinaryLongOp(first, op); + case Const.T_FLOAT: + return createBinaryFloatOp(first); + case Const.T_DOUBLE: + return createBinaryDoubleOp(first); + default: + throw new IllegalArgumentException("Invalid type " + type); } } + /** + * Create branch instruction by given opcode, except LOOKUPSWITCH and TABLESWITCH. For those you should use the SWITCH + * compound instruction. + */ + public static BranchInstruction createBranchInstruction(final short opcode, final InstructionHandle target) { + switch (opcode) { + case Const.IFEQ: + return new IFEQ(target); + case Const.IFNE: + return new IFNE(target); + case Const.IFLT: + return new IFLT(target); + case Const.IFGE: + return new IFGE(target); + case Const.IFGT: + return new IFGT(target); + case Const.IFLE: + return new IFLE(target); + case Const.IF_ICMPEQ: + return new IF_ICMPEQ(target); + case Const.IF_ICMPNE: + return new IF_ICMPNE(target); + case Const.IF_ICMPLT: + return new IF_ICMPLT(target); + case Const.IF_ICMPGE: + return new IF_ICMPGE(target); + case Const.IF_ICMPGT: + return new IF_ICMPGT(target); + case Const.IF_ICMPLE: + return new IF_ICMPLE(target); + case Const.IF_ACMPEQ: + return new IF_ACMPEQ(target); + case Const.IF_ACMPNE: + return new IF_ACMPNE(target); + case Const.GOTO: + return new GOTO(target); + case Const.JSR: + return new JSR(target); + case Const.IFNULL: + return new IFNULL(target); + case Const.IFNONNULL: + return new IFNONNULL(target); + case Const.GOTO_W: + return new GOTO_W(target); + case Const.JSR_W: + return new JSR_W(target); + default: + throw new IllegalArgumentException("Invalid opcode: " + opcode); + } + } /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ - public static StackInstruction createPop( final int size ) { - return (size == 2) ? InstructionConst.POP2 : InstructionConst.POP; + public static StackInstruction createDup(final int size) { + return size == 2 ? InstructionConst.DUP2 : InstructionConst.DUP; } - /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ - public static StackInstruction createDup( final int size ) { - return (size == 2) ? InstructionConst.DUP2 : InstructionConst.DUP; + public static StackInstruction createDup_1(final int size) { + return size == 2 ? InstructionConst.DUP2_X1 : InstructionConst.DUP_X1; } - /** * @param size size of operand, either 1 (int, e.g.) or 2 (double) */ - public static StackInstruction createDup_2( final int size ) { - return (size == 2) ? InstructionConst.DUP2_X2 : InstructionConst.DUP_X2; + public static StackInstruction createDup_2(final int size) { + return size == 2 ? InstructionConst.DUP2_X2 : InstructionConst.DUP_X2; } + /** + * @param index index of local variable + */ + public static LocalVariableInstruction createLoad(final Type type, final int index) { + switch (type.getType()) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + return new ILOAD(index); + case Const.T_FLOAT: + return new FLOAD(index); + case Const.T_DOUBLE: + return new DLOAD(index); + case Const.T_LONG: + return new LLOAD(index); + case Const.T_ARRAY: + case Const.T_OBJECT: + return new ALOAD(index); + default: + throw new IllegalArgumentException("Invalid type " + type); + } + } /** - * @param size size of operand, either 1 (int, e.g.) or 2 (double) + * Create "null" value for reference types, 0 for basic types like int */ - public static StackInstruction createDup_1( final int size ) { - return (size == 2) ? InstructionConst.DUP2_X1 : InstructionConst.DUP_X1; + public static Instruction createNull(final Type type) { + switch (type.getType()) { + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.ACONST_NULL; + case Const.T_INT: + case Const.T_SHORT: + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + return InstructionConst.ICONST_0; + case Const.T_FLOAT: + return InstructionConst.FCONST_0; + case Const.T_DOUBLE: + return InstructionConst.DCONST_0; + case Const.T_LONG: + return InstructionConst.LCONST_0; + case Const.T_VOID: + return InstructionConst.NOP; + default: + throw new IllegalArgumentException("Invalid type: " + type); + } } + /** + * @param size size of operand, either 1 (int, e.g.) or 2 (double) + */ + public static StackInstruction createPop(final int size) { + return size == 2 ? InstructionConst.POP2 : InstructionConst.POP; + } /** - * @param index index of local variable + * Create typed return */ - public static LocalVariableInstruction createStore( final Type type, final int index ) { + public static ReturnInstruction createReturn(final Type type) { switch (type.getType()) { - case Const.T_BOOLEAN: - case Const.T_CHAR: - case Const.T_BYTE: - case Const.T_SHORT: - case Const.T_INT: - return new ISTORE(index); - case Const.T_FLOAT: - return new FSTORE(index); - case Const.T_DOUBLE: - return new DSTORE(index); - case Const.T_LONG: - return new LSTORE(index); - case Const.T_ARRAY: - case Const.T_OBJECT: - return new ASTORE(index); - default: - throw new IllegalArgumentException("Invalid type " + type); + case Const.T_ARRAY: + case Const.T_OBJECT: + return InstructionConst.ARETURN; + case Const.T_INT: + case Const.T_SHORT: + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + return InstructionConst.IRETURN; + case Const.T_FLOAT: + return InstructionConst.FRETURN; + case Const.T_DOUBLE: + return InstructionConst.DRETURN; + case Const.T_LONG: + return InstructionConst.LRETURN; + case Const.T_VOID: + return InstructionConst.RETURN; + default: + throw new IllegalArgumentException("Invalid type: " + type); } } - /** * @param index index of local variable */ - public static LocalVariableInstruction createLoad( final Type type, final int index ) { + public static LocalVariableInstruction createStore(final Type type, final int index) { switch (type.getType()) { - case Const.T_BOOLEAN: - case Const.T_CHAR: - case Const.T_BYTE: - case Const.T_SHORT: - case Const.T_INT: - return new ILOAD(index); - case Const.T_FLOAT: - return new FLOAD(index); - case Const.T_DOUBLE: - return new DLOAD(index); - case Const.T_LONG: - return new LLOAD(index); - case Const.T_ARRAY: - case Const.T_OBJECT: - return new ALOAD(index); - default: - throw new IllegalArgumentException("Invalid type " + type); + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + return new ISTORE(index); + case Const.T_FLOAT: + return new FSTORE(index); + case Const.T_DOUBLE: + return new DSTORE(index); + case Const.T_LONG: + return new LSTORE(index); + case Const.T_ARRAY: + case Const.T_OBJECT: + return new ASTORE(index); + default: + throw new IllegalArgumentException("Invalid type " + type); } } + /** + * Create reference to 'this' + */ + public static Instruction createThis() { + return new ALOAD(0); + } + + private static boolean isString(final Type type) { + return type instanceof ObjectType && ((ObjectType) type).getClassName().equals("java.lang.String"); + } /** - * @param type type of elements of array, i.e., array.getElementType() + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - public static ArrayInstruction createArrayLoad( final Type type ) { - switch (type.getType()) { - case Const.T_BOOLEAN: - case Const.T_BYTE: - return InstructionConst.BALOAD; - case Const.T_CHAR: - return InstructionConst.CALOAD; - case Const.T_SHORT: - return InstructionConst.SALOAD; - case Const.T_INT: - return InstructionConst.IALOAD; - case Const.T_FLOAT: - return InstructionConst.FALOAD; - case Const.T_DOUBLE: - return InstructionConst.DALOAD; - case Const.T_LONG: - return InstructionConst.LALOAD; - case Const.T_ARRAY: - case Const.T_OBJECT: - return InstructionConst.AALOAD; - default: - throw new IllegalArgumentException("Invalid type " + type); - } + @Deprecated + protected ClassGen cg; + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected ConstantPoolGen cp; + + /** + * Initialize with ClassGen object + */ + public InstructionFactory(final ClassGen cg) { + this(cg, cg.getConstantPool()); } + public InstructionFactory(final ClassGen cg, final ConstantPoolGen cp) { + this.cg = cg; + this.cp = cp; + } /** - * @param type type of elements of array, i.e., array.getElementType() + * Initialize just with ConstantPoolGen object */ - public static ArrayInstruction createArrayStore( final Type type ) { - switch (type.getType()) { - case Const.T_BOOLEAN: - case Const.T_BYTE: - return InstructionConst.BASTORE; - case Const.T_CHAR: - return InstructionConst.CASTORE; - case Const.T_SHORT: - return InstructionConst.SASTORE; - case Const.T_INT: - return InstructionConst.IASTORE; - case Const.T_FLOAT: - return InstructionConst.FASTORE; - case Const.T_DOUBLE: - return InstructionConst.DASTORE; - case Const.T_LONG: - return InstructionConst.LASTORE; - case Const.T_ARRAY: - case Const.T_OBJECT: - return InstructionConst.AASTORE; - default: - throw new IllegalArgumentException("Invalid type " + type); + public InstructionFactory(final ConstantPoolGen cp) { + this(null, cp); + } + + public Instruction createAppend(final Type type) { + final byte t = type.getType(); + if (isString(type)) { + return createInvoke(appendMethodObjects[0], Const.INVOKEVIRTUAL); + } + switch (t) { + case Const.T_BOOLEAN: + case Const.T_CHAR: + case Const.T_FLOAT: + case Const.T_DOUBLE: + case Const.T_BYTE: + case Const.T_SHORT: + case Const.T_INT: + case Const.T_LONG: + return createInvoke(appendMethodObjects[t], Const.INVOKEVIRTUAL); + case Const.T_ARRAY: + case Const.T_OBJECT: + return createInvoke(appendMethodObjects[1], Const.INVOKEVIRTUAL); + default: + throw new IllegalArgumentException("No append for this type? " + type); } } /** - * Create conversion operation for two stack operands, this may be an I2C, - * instruction, e.g., if the operands are basic types and CHECKCAST if they - * are reference types. - */ - public Instruction createCast( final Type src_type, final Type dest_type ) { - if ((src_type instanceof BasicType) && (dest_type instanceof BasicType)) { - final byte dest = dest_type.getType(); - byte src = src_type.getType(); - if (dest == Const.T_LONG - && (src == Const.T_CHAR || src == Const.T_BYTE || src == Const.T_SHORT)) { + * Create conversion operation for two stack operands, this may be an I2C, instruction, e.g., if the operands are basic + * types and CHECKCAST if they are reference types. + */ + public Instruction createCast(final Type srcType, final Type destType) { + if (srcType instanceof BasicType && destType instanceof BasicType) { + final byte dest = destType.getType(); + byte src = srcType.getType(); + if (dest == Const.T_LONG && (src == Const.T_CHAR || src == Const.T_BYTE || src == Const.T_SHORT)) { src = Const.T_INT; } - final String name = "com.sun.org.apache.bcel.internal.generic." + short_names[src - Const.T_CHAR] + "2" - + short_names[dest - Const.T_CHAR]; + final String name = "com.sun.org.apache.bcel.internal.generic." + shortNames[src - Const.T_CHAR] + "2" + shortNames[dest - Const.T_CHAR]; Instruction i = null; try { - i = (Instruction) java.lang.Class.forName(name).getDeclaredConstructor().newInstance(); + i = (Instruction) Class.forName(name).getDeclaredConstructor().newInstance();; } catch (final Exception e) { throw new IllegalArgumentException("Could not find instruction: " + name, e); } return i; - } else if ((src_type instanceof ReferenceType) && (dest_type instanceof ReferenceType)) { - if (dest_type instanceof ArrayType) { - return new CHECKCAST(cp.addArrayClass((ArrayType) dest_type)); - } - return new CHECKCAST(cp.addClass(((ObjectType) dest_type).getClassName())); - } else { - throw new IllegalArgumentException("Cannot cast " + src_type + " to " + dest_type); } + if (!(srcType instanceof ReferenceType) || !(destType instanceof ReferenceType)) { + throw new IllegalArgumentException("Cannot cast " + srcType + " to " + destType); + } + if (destType instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) destType)); + } + return new CHECKCAST(cp.addClass(((ObjectType) destType).getClassName())); } - - public GETFIELD createGetField( final String class_name, final String name, final Type t ) { - return new GETFIELD(cp.addFieldref(class_name, name, t.getSignature())); + public CHECKCAST createCheckCast(final ReferenceType t) { + if (t instanceof ArrayType) { + return new CHECKCAST(cp.addArrayClass((ArrayType) t)); + } + return new CHECKCAST(cp.addClass((ObjectType) t)); } - - public GETSTATIC createGetStatic( final String class_name, final String name, final Type t ) { - return new GETSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + /** + * Uses PUSH to push a constant value onto the stack. + * + * @param value must be of type Number, Boolean, Character or String + */ + public Instruction createConstant(final Object value) { + PUSH push; + if (value instanceof Number) { + push = new PUSH(cp, (Number) value); + } else if (value instanceof String) { + push = new PUSH(cp, (String) value); + } else if (value instanceof Boolean) { + push = new PUSH(cp, (Boolean) value); + } else if (value instanceof Character) { + push = new PUSH(cp, (Character) value); + } else { + throw new ClassGenException("Illegal type: " + value.getClass()); + } + return push.getInstruction(); } - - public PUTFIELD createPutField( final String class_name, final String name, final Type t ) { - return new PUTFIELD(cp.addFieldref(class_name, name, t.getSignature())); + /** + * Create a field instruction. + * + * @param className name of the accessed class + * @param name name of the referenced field + * @param type type of field + * @param kind how to access, i.e., GETFIELD, PUTFIELD, GETSTATIC, PUTSTATIC + * @see Const + */ + public FieldInstruction createFieldAccess(final String className, final String name, final Type type, final short kind) { + int index; + final String signature = type.getSignature(); + index = cp.addFieldref(className, name, signature); + switch (kind) { + case Const.GETFIELD: + return new GETFIELD(index); + case Const.PUTFIELD: + return new PUTFIELD(index); + case Const.GETSTATIC: + return new GETSTATIC(index); + case Const.PUTSTATIC: + return new PUTSTATIC(index); + default: + throw new IllegalArgumentException("Unknown getfield kind:" + kind); + } } - - public PUTSTATIC createPutStatic( final String class_name, final String name, final Type t ) { - return new PUTSTATIC(cp.addFieldref(class_name, name, t.getSignature())); + public GETFIELD createGetField(final String className, final String name, final Type t) { + return new GETFIELD(cp.addFieldref(className, name, t.getSignature())); } - - public CHECKCAST createCheckCast( final ReferenceType t ) { - if (t instanceof ArrayType) { - return new CHECKCAST(cp.addArrayClass((ArrayType) t)); - } - return new CHECKCAST(cp.addClass((ObjectType) t)); + public GETSTATIC createGetStatic(final String className, final String name, final Type t) { + return new GETSTATIC(cp.addFieldref(className, name, t.getSignature())); } - - public INSTANCEOF createInstanceOf( final ReferenceType t ) { + public INSTANCEOF createInstanceOf(final ReferenceType t) { if (t instanceof ArrayType) { return new INSTANCEOF(cp.addArrayClass((ArrayType) t)); } return new INSTANCEOF(cp.addClass((ObjectType) t)); } + private InvokeInstruction createInvoke(final MethodObject m, final short kind) { + return createInvoke(m.className, m.name, m.resultType, m.argTypes, kind); + } - public NEW createNew( final ObjectType t ) { - return new NEW(cp.addClass(t)); + /** + * Create an invoke instruction. (Except for invokedynamic.) + * + * @param className name of the called class + * @param name name of the called method + * @param retType return type of method + * @param argTypes argument types of method + * @param kind how to invoke, i.e., INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL + * @see Const + */ + public InvokeInstruction createInvoke(final String className, final String name, final Type retType, final Type[] argTypes, final short kind) { + return createInvoke(className, name, retType, argTypes, kind, kind == Const.INVOKEINTERFACE); } + /** + * Create an invoke instruction. (Except for invokedynamic.) + * + * @param className name of the called class + * @param name name of the called method + * @param retType return type of method + * @param argTypes argument types of method + * @param kind how to invoke: INVOKEINTERFACE, INVOKESTATIC, INVOKEVIRTUAL, or INVOKESPECIAL + * @param useInterface force use of InterfaceMethodref + * @return A new InvokeInstruction. + * @since 6.5.0 + */ + public InvokeInstruction createInvoke(final String className, final String name, final Type retType, final Type[] argTypes, final short kind, + final boolean useInterface) { + if (kind != Const.INVOKESPECIAL && kind != Const.INVOKEVIRTUAL && kind != Const.INVOKESTATIC && kind != Const.INVOKEINTERFACE + && kind != Const.INVOKEDYNAMIC) { + throw new IllegalArgumentException("Unknown invoke kind: " + kind); + } + int index; + int nargs = 0; + final String signature = Type.getMethodSignature(retType, argTypes); + for (final Type argType : argTypes) { + nargs += argType.getSize(); + } + if (useInterface) { + index = cp.addInterfaceMethodref(className, name, signature); + } else { + index = cp.addMethodref(className, name, signature); + } + switch (kind) { + case Const.INVOKESPECIAL: + return new INVOKESPECIAL(index); + case Const.INVOKEVIRTUAL: + return new INVOKEVIRTUAL(index); + case Const.INVOKESTATIC: + return new INVOKESTATIC(index); + case Const.INVOKEINTERFACE: + return new INVOKEINTERFACE(index, nargs + 1); + case Const.INVOKEDYNAMIC: + return new INVOKEDYNAMIC(index); + default: + // Can't happen + throw new IllegalStateException("Unknown invoke kind: " + kind); + } + } + + public NEW createNew(final ObjectType t) { + return new NEW(cp.addClass(t)); + } - public NEW createNew( final String s ) { + public NEW createNew(final String s) { return createNew(ObjectType.getInstance(s)); } /** * Create new array of given size and type. * - * @return an instruction that creates the corresponding array at runtime, - * i.e. is an AllocationInstruction + * @return an instruction that creates the corresponding array at runtime, i.e. is an AllocationInstruction */ - public Instruction createNewArray( final Type t, final short dim ) { + public Instruction createNewArray(final Type t, final short dim) { if (dim == 1) { if (t instanceof ObjectType) { return new ANEWARRAY(cp.addClass((ObjectType) t)); - } else if (t instanceof ArrayType) { + } + if (t instanceof ArrayType) { return new ANEWARRAY(cp.addArrayClass((ArrayType) t)); - } else { - return new NEWARRAY(t.getType()); } + return new NEWARRAY(t.getType()); } ArrayType at; if (t instanceof ArrayType) { @@ -699,101 +700,40 @@ } /** - * Create "null" value for reference types, 0 for basic types like int + * Create a call to the most popular System.out.println() method. + * + * @param s the string to print */ - public static Instruction createNull( final Type type ) { - switch (type.getType()) { - case Const.T_ARRAY: - case Const.T_OBJECT: - return InstructionConst.ACONST_NULL; - case Const.T_INT: - case Const.T_SHORT: - case Const.T_BOOLEAN: - case Const.T_CHAR: - case Const.T_BYTE: - return InstructionConst.ICONST_0; - case Const.T_FLOAT: - return InstructionConst.FCONST_0; - case Const.T_DOUBLE: - return InstructionConst.DCONST_0; - case Const.T_LONG: - return InstructionConst.LCONST_0; - case Const.T_VOID: - return InstructionConst.NOP; - default: - throw new IllegalArgumentException("Invalid type: " + type); - } + public InstructionList createPrintln(final String s) { + final InstructionList il = new InstructionList(); + il.append(createGetStatic("java.lang.System", "out", Type.getType("Ljava/io/PrintStream;"))); + il.append(new PUSH(cp, s)); + final MethodObject methodObject = new MethodObject("java.io.PrintStream", "println", Type.VOID, new Type[] { Type.getType("Ljava/lang/String;") }); + il.append(createInvoke(methodObject, Const.INVOKEVIRTUAL)); + return il; } - /** - * Create branch instruction by given opcode, except LOOKUPSWITCH and - * TABLESWITCH. For those you should use the SWITCH compound instruction. - */ - public static BranchInstruction createBranchInstruction( final short opcode, - final InstructionHandle target ) { - switch (opcode) { - case Const.IFEQ: - return new IFEQ(target); - case Const.IFNE: - return new IFNE(target); - case Const.IFLT: - return new IFLT(target); - case Const.IFGE: - return new IFGE(target); - case Const.IFGT: - return new IFGT(target); - case Const.IFLE: - return new IFLE(target); - case Const.IF_ICMPEQ: - return new IF_ICMPEQ(target); - case Const.IF_ICMPNE: - return new IF_ICMPNE(target); - case Const.IF_ICMPLT: - return new IF_ICMPLT(target); - case Const.IF_ICMPGE: - return new IF_ICMPGE(target); - case Const.IF_ICMPGT: - return new IF_ICMPGT(target); - case Const.IF_ICMPLE: - return new IF_ICMPLE(target); - case Const.IF_ACMPEQ: - return new IF_ACMPEQ(target); - case Const.IF_ACMPNE: - return new IF_ACMPNE(target); - case Const.GOTO: - return new GOTO(target); - case Const.JSR: - return new JSR(target); - case Const.IFNULL: - return new IFNULL(target); - case Const.IFNONNULL: - return new IFNONNULL(target); - case Const.GOTO_W: - return new GOTO_W(target); - case Const.JSR_W: - return new JSR_W(target); - default: - throw new IllegalArgumentException("Invalid opcode: " + opcode); - } + public PUTFIELD createPutField(final String className, final String name, final Type t) { + return new PUTFIELD(cp.addFieldref(className, name, t.getSignature())); } - - public void setClassGen( final ClassGen c ) { - cg = c; + public PUTSTATIC createPutStatic(final String className, final String name, final Type t) { + return new PUTSTATIC(cp.addFieldref(className, name, t.getSignature())); } - public ClassGen getClassGen() { return cg; } - - public void setConstantPool( final ConstantPoolGen c ) { - cp = c; + public ConstantPoolGen getConstantPool() { + return cp; } + public void setClassGen(final ClassGen c) { + cg = c; + } - public ConstantPoolGen getConstantPool() { - return cp; + public void setConstantPool(final ConstantPoolGen c) { + cp = c; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionHandle.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,16 +28,12 @@ import com.sun.org.apache.bcel.internal.classfile.Utility; /** - * Instances of this class give users a handle to the instructions contained in - * an InstructionList. Instruction objects may be used more than once within a - * list, this is useful because it saves memory and may be much faster. + * Instances of this class give users a handle to the instructions contained in an InstructionList. Instruction objects + * may be used more than once within a list, this is useful because it saves memory and may be much faster. * - * Within an InstructionList an InstructionHandle object is wrapped - * around all instructions, i.e., it implements a cell in a - * doubly-linked list. From the outside only the next and the - * previous instruction (handle) are accessible. One - * can traverse the list via an Enumeration returned by - * InstructionList.elements(). + * Within an InstructionList an InstructionHandle object is wrapped around all instructions, i.e., it implements a cell + * in a doubly-linked list. From the outside only the next and the previous instruction (handle) are accessible. One can + * traverse the list via an Enumeration returned by InstructionList.elements(). * * @see Instruction * @see BranchHandle @@ -46,121 +42,86 @@ */ public class InstructionHandle { - private InstructionHandle next; - private InstructionHandle prev; - private Instruction instruction; - - private int i_position = -1; // byte code offset of instruction - - private Set targeters; - private Map attributes; - - /** - * Does nothing. + * Empty array. * - * @deprecated Does nothing as of 6.3.1. + * @since 6.6.0 */ - @Deprecated - protected void addHandle() { - // noop - } - - public final InstructionHandle getNext() { - return next; - } - - - public final InstructionHandle getPrev() { - return prev; - } - - - public final Instruction getInstruction() { - return instruction; - } + public static final InstructionHandle[] EMPTY_ARRAY = {}; + /** + * Empty array. + */ + static final InstructionTargeter[] EMPTY_INSTRUCTION_TARGETER_ARRAY = {}; /** - * Replace current instruction contained in this handle. - * Old instruction is disposed using Instruction.dispose(). + * Factory method. */ - public void setInstruction( final Instruction i ) { // Overridden in BranchHandle TODO could be package-protected? - if (i == null) { - throw new ClassGenException("Assigning null to handle"); - } - if ((this.getClass() != BranchHandle.class) && (i instanceof BranchInstruction)) { - throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); - } - if (instruction != null) { - instruction.dispose(); - } - instruction = i; + static InstructionHandle getInstructionHandle(final Instruction i) { + return new InstructionHandle(i); } + private InstructionHandle next; + private InstructionHandle prev; + + private Instruction instruction; /** - * Temporarily swap the current instruction, without disturbing - * anything. Meant to be used by a debugger, implementing - * breakpoints. Current instruction is returned. - *

    - * Warning: if this is used on a BranchHandle then some methods such as - * getPosition() will still refer to the original cached instruction, whereas - * other BH methods may affect the cache and the replacement instruction. + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - // See BCEL-273 - // TODO remove this method in any redesign of BCEL - public Instruction swapInstruction( final Instruction i ) { - final Instruction oldInstruction = instruction; - instruction = i; - return oldInstruction; - } + @Deprecated + protected int i_position = -1; // byte code offset of instruction + private Set targeters; + private Map attributes; - /*private*/protected InstructionHandle(final Instruction i) { + protected InstructionHandle(final Instruction i) { setInstruction(i); } - /** Factory method. + /** + * Convenience method, simply calls accept() on the contained instruction. + * + * @param v Visitor object */ - static InstructionHandle getInstructionHandle( final Instruction i ) { - return new InstructionHandle(i); + public void accept(final Visitor v) { + instruction.accept(v); } - /** - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions()' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. + * Add an attribute to an instruction handle. * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length + * @param key the key object to store/retrieve the attribute + * @param attr the attribute to associate with this handle */ - protected int updatePosition( final int offset, final int max_offset ) { - i_position += offset; - return 0; + public void addAttribute(final Object key, final Object attr) { + if (attributes == null) { + attributes = new HashMap<>(3); + } + attributes.put(key, attr); } - - /** @return the position, i.e., the byte code offset of the contained - * instruction. This is accurate only after - * InstructionList.setPositions() has been called. + /** + * Does nothing. + * + * @deprecated Does nothing as of 6.3.1. */ - public int getPosition() { - return i_position; + @Deprecated + protected void addHandle() { + // noop } - - /** Set the position, i.e., the byte code offset of the contained - * instruction. + /** + * Denote this handle is being referenced by t. */ - void setPosition( final int pos ) { - i_position = pos; + public void addTargeter(final InstructionTargeter t) { + if (targeters == null) { + targeters = new HashSet<>(); + } + // if(!targeters.contains(t)) + targeters.add(t); } - /** * Delete contents, i.e., remove user access. */ @@ -173,126 +134,109 @@ removeAllTargeters(); } - - /** Remove all targeters, if any. + /** + * Get attribute of an instruction handle. + * + * @param key the key object to store/retrieve the attribute */ - public void removeAllTargeters() { - if (targeters != null) { - targeters.clear(); + public Object getAttribute(final Object key) { + if (attributes != null) { + return attributes.get(key); } + return null; } - /** - * Denote this handle isn't referenced anymore by t. + * @return all attributes associated with this handle */ - public void removeTargeter( final InstructionTargeter t ) { - if (targeters != null) { - targeters.remove(t); + public Collection getAttributes() { + if (attributes == null) { + attributes = new HashMap<>(3); } + return attributes.values(); + } + + public final Instruction getInstruction() { + return instruction; } + public final InstructionHandle getNext() { + return next; + } /** - * Denote this handle is being referenced by t. + * @return the position, i.e., the byte code offset of the contained instruction. This is accurate only after + * InstructionList.setPositions() has been called. */ - public void addTargeter( final InstructionTargeter t ) { - if (targeters == null) { - targeters = new HashSet<>(); - } - //if(!targeters.contains(t)) - targeters.add(t); + public int getPosition() { + return i_position; } - - public boolean hasTargeters() { - return (targeters != null) && (targeters.size() > 0); + public final InstructionHandle getPrev() { + return prev; } - /** * @return null, if there are no targeters */ public InstructionTargeter[] getTargeters() { if (!hasTargeters()) { - return new InstructionTargeter[0]; + return EMPTY_INSTRUCTION_TARGETER_ARRAY; } final InstructionTargeter[] t = new InstructionTargeter[targeters.size()]; targeters.toArray(t); return t; } - - /** @return a (verbose) string representation of the contained instruction. - */ - public String toString( final boolean verbose ) { - return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); - } - - - /** @return a string representation of the contained instruction. - */ - @Override - public String toString() { - return toString(true); + public boolean hasTargeters() { + return targeters != null && !targeters.isEmpty(); } - - /** Add an attribute to an instruction handle. - * - * @param key the key object to store/retrieve the attribute - * @param attr the attribute to associate with this handle + /** + * Remove all targeters, if any. */ - public void addAttribute( final Object key, final Object attr ) { - if (attributes == null) { - attributes = new HashMap<>(3); + public void removeAllTargeters() { + if (targeters != null) { + targeters.clear(); } - attributes.put(key, attr); } - - /** Delete an attribute of an instruction handle. + /** + * Delete an attribute of an instruction handle. * * @param key the key object to retrieve the attribute */ - public void removeAttribute( final Object key ) { + public void removeAttribute(final Object key) { if (attributes != null) { attributes.remove(key); } } - - /** Get attribute of an instruction handle. - * - * @param key the key object to store/retrieve the attribute + /** + * Denote this handle isn't referenced anymore by t. */ - public Object getAttribute( final Object key ) { - if (attributes != null) { - return attributes.get(key); + public void removeTargeter(final InstructionTargeter t) { + if (targeters != null) { + targeters.remove(t); } - return null; } - - /** @return all attributes associated with this handle + /** + * Replace current instruction contained in this handle. Old instruction is disposed using Instruction.dispose(). */ - public Collection getAttributes() { - if (attributes == null) { - attributes = new HashMap<>(3); + public void setInstruction(final Instruction i) { // Overridden in BranchHandle TODO could be package-protected? + if (i == null) { + throw new ClassGenException("Assigning null to handle"); } - return attributes.values(); - } - - - /** Convenience method, simply calls accept() on the contained instruction. - * - * @param v Visitor object - */ - public void accept( final Visitor v ) { - instruction.accept(v); + if (this.getClass() != BranchHandle.class && i instanceof BranchInstruction) { + throw new ClassGenException("Assigning branch instruction " + i + " to plain handle"); + } + if (instruction != null) { + instruction.dispose(); + } + instruction = i; } - /** * @param next the next to set * @since 6.0 @@ -302,6 +246,12 @@ return next; } + /** + * Set the position, i.e., the byte code offset of the contained instruction. + */ + void setPosition(final int pos) { + i_position = pos; + } /** * @param prev the prev to set @@ -311,4 +261,48 @@ this.prev = prev; return prev; } + + /** + * Temporarily swap the current instruction, without disturbing anything. Meant to be used by a debugger, implementing + * breakpoints. Current instruction is returned. + *

    + * Warning: if this is used on a BranchHandle then some methods such as getPosition() will still refer to the original + * cached instruction, whereas other BH methods may affect the cache and the replacement instruction. + */ + // See BCEL-273 + // TODO remove this method in any redesign of BCEL + public Instruction swapInstruction(final Instruction i) { + final Instruction oldInstruction = instruction; + instruction = i; + return oldInstruction; + } + + /** + * @return a string representation of the contained instruction. + */ + @Override + public String toString() { + return toString(true); + } + + /** + * @return a (verbose) string representation of the contained instruction. + */ + public String toString(final boolean verbose) { + return Utility.format(i_position, 4, false, ' ') + ": " + instruction.toString(verbose); + } + + /** + * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable + * length instructions 'setPositions()' performs multiple passes over the instruction list to calculate the correct + * (byte) positions and offsets by calling this function. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param maxOffset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + protected int updatePosition(final int offset, final int maxOffset) { + i_position += offset; + return 0; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Instruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -29,127 +29,59 @@ /** * Abstract super class for all Java byte codes. * - * @LastModified: July 2020 + * @LastModified: Feb 2023 */ public abstract class Instruction implements Cloneable { - private short length = 1; // Length of instruction in bytes - private short opcode = -1; // Opcode number + static final Instruction[] EMPTY_ARRAY = {}; private static InstructionComparator cmp = InstructionComparator.DEFAULT; - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. - */ - Instruction() { - } - - - public Instruction(final short opcode, final short length) { - this.length = length; - this.opcode = opcode; - } - - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(opcode); // Common for all instructions - } - - - /** @return name of instruction, i.e., opcode name - */ - public String getName() { - return Const.getOpcodeName(opcode); - } - - - /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" + * Gets Comparator object used in the equals() method to determine equality of instructions. * - * @param verbose long/short format switch - * @return mnemonic for instruction - */ - public String toString( final boolean verbose ) { - if (verbose) { - return getName() + "[" + opcode + "](" + length + ")"; - } - return getName(); - } - - - /** - * @return mnemonic for instruction in verbose format - */ - @Override - public String toString() { - return toString(true); - } - - - /** - * @return mnemonic for instruction with sumbolic references resolved + * @return currently used comparator for equals() + * @deprecated (6.0) use the built in comparator, or wrap this class in another object that implements these methods */ - public String toString( final ConstantPool cp ) { - return toString(false); + @Deprecated + public static InstructionComparator getComparator() { + return cmp; } - /** - * Use with caution, since `BranchInstruction's have a `target' reference which - * is not copied correctly (only basic types are). This also applies for - * `Select' instructions with their multiple branch targets. + * Tests if the value can fit in a byte (signed) * - * @see BranchInstruction - * @return (shallow) copy of an instruction + * @param value the value to check + * @return true if the value is in range + * @since 6.0 */ - public Instruction copy() { - Instruction i = null; - // "Constant" instruction, no need to duplicate - if (InstructionConst.getInstruction(this.getOpcode()) != null) { - i = this; - } else { - try { - i = (Instruction) clone(); - } catch (final CloneNotSupportedException e) { - System.err.println(e); - } - } - return i; + public static boolean isValidByte(final int value) { + return value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE; } - /** - * Read needed data (e.g. index) from file. + * Tests if the value can fit in a short (signed) * - * @param bytes byte sequence to read from - * @param wide "wide" instruction flag - * @throws IOException may be thrown if the implementation needs to read data from the file + * @param value the value to check + * @return true if the value is in range + * @since 6.0 */ - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + public static boolean isValidShort(final int value) { + return value >= Short.MIN_VALUE && value <= Short.MAX_VALUE; } - /** - * Read an instruction from (byte code) input stream and return the - * appropiate object. + * Reads an instruction from (byte code) input stream and return the appropriate object. *

    - * If the Instruction is defined in {@link InstructionConst}, then the - * singleton instance is returned. + * If the Instruction is defined in {@link InstructionConst}, then the singleton instance is returned. + *

    * @param bytes input stream bytes * @return instruction object being read + * @throws IOException Thrown when an I/O exception of some sort has occurred. * @see InstructionConst#getInstruction(int) */ // @since 6.0 no longer final - public static Instruction readInstruction( final ByteSequence bytes ) throws IOException { + public static Instruction readInstruction(final ByteSequence bytes) throws IOException { boolean wide = false; short opcode = (short) bytes.readUnsignedByte(); Instruction obj = null; @@ -163,304 +95,303 @@ } switch (opcode) { - case Const.BIPUSH: - obj = new BIPUSH(); - break; - case Const.SIPUSH: - obj = new SIPUSH(); - break; - case Const.LDC: - obj = new LDC(); - break; - case Const.LDC_W: - obj = new LDC_W(); - break; - case Const.LDC2_W: - obj = new LDC2_W(); - break; - case Const.ILOAD: - obj = new ILOAD(); - break; - case Const.LLOAD: - obj = new LLOAD(); - break; - case Const.FLOAD: - obj = new FLOAD(); - break; - case Const.DLOAD: - obj = new DLOAD(); - break; - case Const.ALOAD: - obj = new ALOAD(); - break; - case Const.ILOAD_0: - obj = new ILOAD(0); - break; - case Const.ILOAD_1: - obj = new ILOAD(1); - break; - case Const.ILOAD_2: - obj = new ILOAD(2); - break; - case Const.ILOAD_3: - obj = new ILOAD(3); - break; - case Const.LLOAD_0: - obj = new LLOAD(0); - break; - case Const.LLOAD_1: - obj = new LLOAD(1); - break; - case Const.LLOAD_2: - obj = new LLOAD(2); - break; - case Const.LLOAD_3: - obj = new LLOAD(3); - break; - case Const.FLOAD_0: - obj = new FLOAD(0); - break; - case Const.FLOAD_1: - obj = new FLOAD(1); - break; - case Const.FLOAD_2: - obj = new FLOAD(2); - break; - case Const.FLOAD_3: - obj = new FLOAD(3); - break; - case Const.DLOAD_0: - obj = new DLOAD(0); - break; - case Const.DLOAD_1: - obj = new DLOAD(1); - break; - case Const.DLOAD_2: - obj = new DLOAD(2); - break; - case Const.DLOAD_3: - obj = new DLOAD(3); - break; - case Const.ALOAD_0: - obj = new ALOAD(0); - break; - case Const.ALOAD_1: - obj = new ALOAD(1); - break; - case Const.ALOAD_2: - obj = new ALOAD(2); - break; - case Const.ALOAD_3: - obj = new ALOAD(3); - break; - case Const.ISTORE: - obj = new ISTORE(); - break; - case Const.LSTORE: - obj = new LSTORE(); - break; - case Const.FSTORE: - obj = new FSTORE(); - break; - case Const.DSTORE: - obj = new DSTORE(); - break; - case Const.ASTORE: - obj = new ASTORE(); - break; - case Const.ISTORE_0: - obj = new ISTORE(0); - break; - case Const.ISTORE_1: - obj = new ISTORE(1); - break; - case Const.ISTORE_2: - obj = new ISTORE(2); - break; - case Const.ISTORE_3: - obj = new ISTORE(3); - break; - case Const.LSTORE_0: - obj = new LSTORE(0); - break; - case Const.LSTORE_1: - obj = new LSTORE(1); - break; - case Const.LSTORE_2: - obj = new LSTORE(2); - break; - case Const.LSTORE_3: - obj = new LSTORE(3); - break; - case Const.FSTORE_0: - obj = new FSTORE(0); - break; - case Const.FSTORE_1: - obj = new FSTORE(1); - break; - case Const.FSTORE_2: - obj = new FSTORE(2); - break; - case Const.FSTORE_3: - obj = new FSTORE(3); - break; - case Const.DSTORE_0: - obj = new DSTORE(0); - break; - case Const.DSTORE_1: - obj = new DSTORE(1); - break; - case Const.DSTORE_2: - obj = new DSTORE(2); - break; - case Const.DSTORE_3: - obj = new DSTORE(3); - break; - case Const.ASTORE_0: - obj = new ASTORE(0); - break; - case Const.ASTORE_1: - obj = new ASTORE(1); - break; - case Const.ASTORE_2: - obj = new ASTORE(2); - break; - case Const.ASTORE_3: - obj = new ASTORE(3); - break; - case Const.IINC: - obj = new IINC(); - break; - case Const.IFEQ: - obj = new IFEQ(); - break; - case Const.IFNE: - obj = new IFNE(); - break; - case Const.IFLT: - obj = new IFLT(); - break; - case Const.IFGE: - obj = new IFGE(); - break; - case Const.IFGT: - obj = new IFGT(); - break; - case Const.IFLE: - obj = new IFLE(); - break; - case Const.IF_ICMPEQ: - obj = new IF_ICMPEQ(); - break; - case Const.IF_ICMPNE: - obj = new IF_ICMPNE(); - break; - case Const.IF_ICMPLT: - obj = new IF_ICMPLT(); - break; - case Const.IF_ICMPGE: - obj = new IF_ICMPGE(); - break; - case Const.IF_ICMPGT: - obj = new IF_ICMPGT(); - break; - case Const.IF_ICMPLE: - obj = new IF_ICMPLE(); - break; - case Const.IF_ACMPEQ: - obj = new IF_ACMPEQ(); - break; - case Const.IF_ACMPNE: - obj = new IF_ACMPNE(); - break; - case Const.GOTO: - obj = new GOTO(); - break; - case Const.JSR: - obj = new JSR(); - break; - case Const.RET: - obj = new RET(); - break; - case Const.TABLESWITCH: - obj = new TABLESWITCH(); - break; - case Const.LOOKUPSWITCH: - obj = new LOOKUPSWITCH(); - break; - case Const.GETSTATIC: - obj = new GETSTATIC(); - break; - case Const.PUTSTATIC: - obj = new PUTSTATIC(); - break; - case Const.GETFIELD: - obj = new GETFIELD(); - break; - case Const.PUTFIELD: - obj = new PUTFIELD(); - break; - case Const.INVOKEVIRTUAL: - obj = new INVOKEVIRTUAL(); - break; - case Const.INVOKESPECIAL: - obj = new INVOKESPECIAL(); - break; - case Const.INVOKESTATIC: - obj = new INVOKESTATIC(); - break; - case Const.INVOKEINTERFACE: - obj = new INVOKEINTERFACE(); - break; - case Const.INVOKEDYNAMIC: - obj = new INVOKEDYNAMIC(); - break; - case Const.NEW: - obj = new NEW(); - break; - case Const.NEWARRAY: - obj = new NEWARRAY(); - break; - case Const.ANEWARRAY: - obj = new ANEWARRAY(); - break; - case Const.CHECKCAST: - obj = new CHECKCAST(); - break; - case Const.INSTANCEOF: - obj = new INSTANCEOF(); - break; - case Const.MULTIANEWARRAY: - obj = new MULTIANEWARRAY(); - break; - case Const.IFNULL: - obj = new IFNULL(); - break; - case Const.IFNONNULL: - obj = new IFNONNULL(); - break; - case Const.GOTO_W: - obj = new GOTO_W(); - break; - case Const.JSR_W: - obj = new JSR_W(); - break; - case Const.BREAKPOINT: - obj = new BREAKPOINT(); - break; - case Const.IMPDEP1: - obj = new IMPDEP1(); - break; - case Const.IMPDEP2: - obj = new IMPDEP2(); - break; - default: - throw new ClassGenException("Illegal opcode detected: " + opcode); + case Const.BIPUSH: + obj = new BIPUSH(); + break; + case Const.SIPUSH: + obj = new SIPUSH(); + break; + case Const.LDC: + obj = new LDC(); + break; + case Const.LDC_W: + obj = new LDC_W(); + break; + case Const.LDC2_W: + obj = new LDC2_W(); + break; + case Const.ILOAD: + obj = new ILOAD(); + break; + case Const.LLOAD: + obj = new LLOAD(); + break; + case Const.FLOAD: + obj = new FLOAD(); + break; + case Const.DLOAD: + obj = new DLOAD(); + break; + case Const.ALOAD: + obj = new ALOAD(); + break; + case Const.ILOAD_0: + obj = new ILOAD(0); + break; + case Const.ILOAD_1: + obj = new ILOAD(1); + break; + case Const.ILOAD_2: + obj = new ILOAD(2); + break; + case Const.ILOAD_3: + obj = new ILOAD(3); + break; + case Const.LLOAD_0: + obj = new LLOAD(0); + break; + case Const.LLOAD_1: + obj = new LLOAD(1); + break; + case Const.LLOAD_2: + obj = new LLOAD(2); + break; + case Const.LLOAD_3: + obj = new LLOAD(3); + break; + case Const.FLOAD_0: + obj = new FLOAD(0); + break; + case Const.FLOAD_1: + obj = new FLOAD(1); + break; + case Const.FLOAD_2: + obj = new FLOAD(2); + break; + case Const.FLOAD_3: + obj = new FLOAD(3); + break; + case Const.DLOAD_0: + obj = new DLOAD(0); + break; + case Const.DLOAD_1: + obj = new DLOAD(1); + break; + case Const.DLOAD_2: + obj = new DLOAD(2); + break; + case Const.DLOAD_3: + obj = new DLOAD(3); + break; + case Const.ALOAD_0: + obj = new ALOAD(0); + break; + case Const.ALOAD_1: + obj = new ALOAD(1); + break; + case Const.ALOAD_2: + obj = new ALOAD(2); + break; + case Const.ALOAD_3: + obj = new ALOAD(3); + break; + case Const.ISTORE: + obj = new ISTORE(); + break; + case Const.LSTORE: + obj = new LSTORE(); + break; + case Const.FSTORE: + obj = new FSTORE(); + break; + case Const.DSTORE: + obj = new DSTORE(); + break; + case Const.ASTORE: + obj = new ASTORE(); + break; + case Const.ISTORE_0: + obj = new ISTORE(0); + break; + case Const.ISTORE_1: + obj = new ISTORE(1); + break; + case Const.ISTORE_2: + obj = new ISTORE(2); + break; + case Const.ISTORE_3: + obj = new ISTORE(3); + break; + case Const.LSTORE_0: + obj = new LSTORE(0); + break; + case Const.LSTORE_1: + obj = new LSTORE(1); + break; + case Const.LSTORE_2: + obj = new LSTORE(2); + break; + case Const.LSTORE_3: + obj = new LSTORE(3); + break; + case Const.FSTORE_0: + obj = new FSTORE(0); + break; + case Const.FSTORE_1: + obj = new FSTORE(1); + break; + case Const.FSTORE_2: + obj = new FSTORE(2); + break; + case Const.FSTORE_3: + obj = new FSTORE(3); + break; + case Const.DSTORE_0: + obj = new DSTORE(0); + break; + case Const.DSTORE_1: + obj = new DSTORE(1); + break; + case Const.DSTORE_2: + obj = new DSTORE(2); + break; + case Const.DSTORE_3: + obj = new DSTORE(3); + break; + case Const.ASTORE_0: + obj = new ASTORE(0); + break; + case Const.ASTORE_1: + obj = new ASTORE(1); + break; + case Const.ASTORE_2: + obj = new ASTORE(2); + break; + case Const.ASTORE_3: + obj = new ASTORE(3); + break; + case Const.IINC: + obj = new IINC(); + break; + case Const.IFEQ: + obj = new IFEQ(); + break; + case Const.IFNE: + obj = new IFNE(); + break; + case Const.IFLT: + obj = new IFLT(); + break; + case Const.IFGE: + obj = new IFGE(); + break; + case Const.IFGT: + obj = new IFGT(); + break; + case Const.IFLE: + obj = new IFLE(); + break; + case Const.IF_ICMPEQ: + obj = new IF_ICMPEQ(); + break; + case Const.IF_ICMPNE: + obj = new IF_ICMPNE(); + break; + case Const.IF_ICMPLT: + obj = new IF_ICMPLT(); + break; + case Const.IF_ICMPGE: + obj = new IF_ICMPGE(); + break; + case Const.IF_ICMPGT: + obj = new IF_ICMPGT(); + break; + case Const.IF_ICMPLE: + obj = new IF_ICMPLE(); + break; + case Const.IF_ACMPEQ: + obj = new IF_ACMPEQ(); + break; + case Const.IF_ACMPNE: + obj = new IF_ACMPNE(); + break; + case Const.GOTO: + obj = new GOTO(); + break; + case Const.JSR: + obj = new JSR(); + break; + case Const.RET: + obj = new RET(); + break; + case Const.TABLESWITCH: + obj = new TABLESWITCH(); + break; + case Const.LOOKUPSWITCH: + obj = new LOOKUPSWITCH(); + break; + case Const.GETSTATIC: + obj = new GETSTATIC(); + break; + case Const.PUTSTATIC: + obj = new PUTSTATIC(); + break; + case Const.GETFIELD: + obj = new GETFIELD(); + break; + case Const.PUTFIELD: + obj = new PUTFIELD(); + break; + case Const.INVOKEVIRTUAL: + obj = new INVOKEVIRTUAL(); + break; + case Const.INVOKESPECIAL: + obj = new INVOKESPECIAL(); + break; + case Const.INVOKESTATIC: + obj = new INVOKESTATIC(); + break; + case Const.INVOKEINTERFACE: + obj = new INVOKEINTERFACE(); + break; + case Const.INVOKEDYNAMIC: + obj = new INVOKEDYNAMIC(); + break; + case Const.NEW: + obj = new NEW(); + break; + case Const.NEWARRAY: + obj = new NEWARRAY(); + break; + case Const.ANEWARRAY: + obj = new ANEWARRAY(); + break; + case Const.CHECKCAST: + obj = new CHECKCAST(); + break; + case Const.INSTANCEOF: + obj = new INSTANCEOF(); + break; + case Const.MULTIANEWARRAY: + obj = new MULTIANEWARRAY(); + break; + case Const.IFNULL: + obj = new IFNULL(); + break; + case Const.IFNONNULL: + obj = new IFNONNULL(); + break; + case Const.GOTO_W: + obj = new GOTO_W(); + break; + case Const.JSR_W: + obj = new JSR_W(); + break; + case Const.BREAKPOINT: + obj = new BREAKPOINT(); + break; + case Const.IMPDEP1: + obj = new IMPDEP1(); + break; + case Const.IMPDEP2: + obj = new IMPDEP2(); + break; + default: + throw new ClassGenException("Illegal opcode detected: " + opcode); } - if (wide - && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) { + if (wide && !(obj instanceof LocalVariableInstruction || obj instanceof RET)) { throw new ClassGenException("Illegal opcode after wide: " + opcode); } obj.setOpcode(opcode); @@ -469,109 +400,129 @@ } /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words consumed from stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically + * Sets comparator to be used for equals(). + * + * @deprecated (6.0) use the built in comparator, or wrap this class in another object that implements these methods */ - public int consumeStack( final ConstantPoolGen cpg ) { - return Const.getConsumeStack(opcode); + @Deprecated + public static void setComparator(final InstructionComparator c) { + cmp = c; } - /** - * This method also gives right results for instructions whose - * effect on the stack depends on the constant pool entry they - * reference. - * @return Number of words produced onto stack by this instruction, - * or Constants.UNPREDICTABLE, if this can not be computed statically + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter */ - public int produceStack( final ConstantPoolGen cpg ) { - return Const.getProduceStack(opcode); - } + @Deprecated + protected short length = 1; // Length of instruction in bytes + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected short opcode = -1; // Opcode number /** - * @return this instructions opcode + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ - public short getOpcode() { - return opcode; + Instruction() { } + public Instruction(final short opcode, final short length) { + this.length = length; + this.opcode = opcode; + } /** - * @return length (in bytes) of instruction + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object */ - public int getLength() { - return length; - } - + public abstract void accept(Visitor v); /** - * Needed in readInstruction and subclasses in this package + * This method also gives right results for instructions whose effect on the stack depends on the constant pool entry + * they reference. + * + * @return Number of words consumed from stack by this instruction, or Constants.UNPREDICTABLE, if this can not be + * computed statically */ - void setOpcode( final short opcode ) { - this.opcode = opcode; + public int consumeStack(final ConstantPoolGen cpg) { + return Const.getConsumeStack(opcode); } - /** - * Needed in readInstruction and subclasses in this package - * @since 6.0 + * Use with caution, since 'BranchInstruction's have a 'target' reference which is not copied correctly (only basic + * types are). This also applies for 'Select' instructions with their multiple branch targets. + * + * @see BranchInstruction + * @return (shallow) copy of an instruction */ - final void setLength( final int length ) { - this.length = (short) length; // TODO check range? + public Instruction copy() { + Instruction i = null; + // "Constant" instruction, no need to duplicate + if (InstructionConst.getInstruction(this.getOpcode()) != null) { + i = this; + } else { + try { + i = (Instruction) clone(); + } catch (final CloneNotSupportedException e) { + System.err.println(e); + } + } + return i; } - - /** Some instructions may be reused, so don't do anything by default. + /** + * Some instructions may be reused, so don't do anything by default. */ void dispose() { } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Dumps instruction as byte code to stream out. * - * @param v Visitor object + * @param out Output stream + * @throws IOException Thrown when an I/O exception of some sort has occurred. */ - public abstract void accept( Visitor v ); - + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(opcode); // Common for all instructions + } - /** Get Comparator object used in the equals() method to determine - * equality of instructions. + /** + * Tests for equality, delegated to comparator * - * @return currently used comparator for equals() - * @deprecated (6.0) use the built in comparator, or wrap this class in another object that implements these methods + * @return true if that is an Instruction and has the same opcode */ - @Deprecated - public static InstructionComparator getComparator() { - return cmp; + @Override + public boolean equals(final Object that) { + return that instanceof Instruction && cmp.equals(this, (Instruction) that); } - - /** Set comparator to be used for equals(). - * @deprecated (6.0) use the built in comparator, or wrap this class in another object that implements these methods + /** + * @return length (in bytes) of instruction */ - @Deprecated - public static void setComparator( final InstructionComparator c ) { - cmp = c; + public int getLength() { + return length; } + /** + * @return name of instruction, i.e., opcode name + */ + public String getName() { + return Const.getOpcodeName(opcode); + } - /** Check for equality, delegated to comparator - * @return true if that is an Instruction and has the same opcode + /** + * @return this instructions opcode */ - @Override - public boolean equals( final Object that ) { - return (that instanceof Instruction) ? cmp.equals(this, (Instruction) that) : false; + public short getOpcode() { + return opcode; } - /** calculate the hashCode of this object + /** + * Gets the hashCode of this object. + * * @return the hashCode * @since 6.0 */ @@ -581,22 +532,70 @@ } /** - * Check if the value can fit in a byte (signed) - * @param value the value to check - * @return true if the value is in range - * @since 6.0 + * Reads needed data (e.g. index) from file. + * + * @param bytes byte sequence to read from + * @param wide "wide" instruction flag + * @throws IOException may be thrown if the implementation needs to read data from the file */ - public static boolean isValidByte(final int value) { - return value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE; + @SuppressWarnings("unused") // thrown by subclasses + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { } /** - * Check if the value can fit in a short (signed) - * @param value the value to check - * @return true if the value is in range + * This method also gives right results for instructions whose effect on the stack depends on the constant pool entry + * they reference. + * + * @return Number of words produced onto stack by this instruction, or Constants.UNPREDICTABLE, if this can not be + * computed statically + */ + public int produceStack(final ConstantPoolGen cpg) { + return Const.getProduceStack(opcode); + } + + /** + * Needed in readInstruction and subclasses in this package + * * @since 6.0 */ - public static boolean isValidShort(final int value) { - return value >= Short.MIN_VALUE && value <= Short.MAX_VALUE; + final void setLength(final int length) { + this.length = (short) length; // TODO check range? + } + + /** + * Needed in readInstruction and subclasses in this package + */ + void setOpcode(final short opcode) { + this.opcode = opcode; + } + + /** + * @return mnemonic for instruction in verbose format + */ + @Override + public String toString() { + return toString(true); + } + + /** + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of instruction>")" + * + * @param verbose long/short format switch + * @return mnemonic for instruction + */ + public String toString(final boolean verbose) { + if (verbose) { + return getName() + "[" + opcode + "](" + length + ")"; + } + return getName(); + } + + /** + * @return mnemonic for instruction with sumbolic references resolved + */ + public String toString(final ConstantPool cp) { + return toString(false); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionList.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -19,114 +19,59 @@ */ package com.sun.org.apache.bcel.internal.generic; -import com.sun.org.apache.bcel.internal.Const; -import com.sun.org.apache.bcel.internal.classfile.Constant; -import com.sun.org.apache.bcel.internal.util.ByteSequence; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.classfile.Constant; +import com.sun.org.apache.bcel.internal.util.ByteSequence; + /** - * This class is a container for a list of Instruction objects. Instructions can be + * This class is a container for a list of Instruction objects. Instructions can be * appended, inserted, moved, deleted, etc.. Instructions are being wrapped into - * InstructionHandles objects that are - * returned upon append/insert operations. They give the user (read only) access - * to the list structure, such that it can be traversed and manipulated in a - * controlled way. + * InstructionHandles objects that are returned upon append/insert operations. They + * give the user (read only) access to the list structure, such that it can be traversed and manipulated in a controlled + * way. * - * A list is finally dumped to a byte code array with getByteCode. + * A list is finally dumped to a byte code array with getByteCode. * * @see Instruction * @see InstructionHandle * @see BranchHandle - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public class InstructionList implements Iterable { - private InstructionHandle start = null; - private InstructionHandle end = null; - private int length = 0; // number of elements in list - private int[] bytePositions; // byte code offsets corresponding to instructions - - /** - * Create (empty) instruction list. - */ - public InstructionList() { - } - - /** - * Create instruction list containing one instruction. - * - * @param i - * initial instruction - */ - public InstructionList(final Instruction i) { - append(i); - } - - /** - * Create instruction list containing one instruction. - * - * @param i - * initial instruction - */ - public InstructionList(final BranchInstruction i) { - append(i); - } - - /** - * Initialize list with (nonnull) compound instruction. Consumes argument - * list, i.e., it becomes empty. - * - * @param c - * compound instruction (list) - */ - public InstructionList(final CompoundInstruction c) { - append(c.getInstructionList()); - } - - /** - * Test for empty list. - */ - public boolean isEmpty() { - return start == null; - } // && end == null - /** - * Find the target instruction (handle) that corresponds to the given target - * position (byte code offset). + * Find the target instruction (handle) that corresponds to the given target position (byte code offset). * - * @param ihs - * array of instruction handles, i.e. il.getInstructionHandles() - * @param pos - * array of positions corresponding to ihs, i.e. il.getInstructionPositions() - * @param count - * length of arrays - * @param target - * target position to search for + * @param ihs array of instruction handles, i.e. il.getInstructionHandles() + * @param pos array of positions corresponding to ihs, i.e. il.getInstructionPositions() + * @param count length of arrays + * @param target target position to search for * @return target position's instruction handle if available */ - public static InstructionHandle findHandle(final InstructionHandle[] ihs, - final int[] pos, final int count, final int target) { + public static InstructionHandle findHandle(final InstructionHandle[] ihs, final int[] pos, final int count, final int target) { int l = 0; int r = count - 1; /* * Do a binary search since the pos array is orderd. */ do { - final int i = (l + r) >>> 1; + final int i = l + r >>> 1; final int j = pos[i]; if (j == target) { return ihs[i]; - } else if (target < j) { + } + if (target < j) { r = i - 1; } else { l = i + 1; @@ -135,32 +80,33 @@ return null; } + private InstructionHandle start; + private InstructionHandle end; + private int length; // number of elements in list + + private int[] bytePositions; // byte code offsets corresponding to instructions + + private List observers; + + /** + * Create (empty) instruction list. + */ + public InstructionList() { + } + /** - * Get instruction handle for instruction at byte code position pos. This - * only works properly, if the list is freshly initialized from a byte array - * or setPositions() has been called before this method. + * Create instruction list containing one instruction. * - * @param pos - * byte code position to search for - * @return target position's instruction handle if available + * @param i initial instruction */ - public InstructionHandle findHandle(final int pos) { - final int[] positions = bytePositions; - InstructionHandle ih = start; - for (int i = 0; i < length; i++) { - if (positions[i] == pos) { - return ih; - } - ih = ih.getNext(); - } - return null; + public InstructionList(final BranchInstruction i) { + append(i); } /** * Initialize instruction list from byte array. * - * @param code - * byte array containing the instructions + * @param code byte array containing the instructions */ public InstructionList(final byte[] code) { int count = 0; // Contains actual length @@ -193,18 +139,16 @@ } catch (final IOException e) { throw new ClassGenException(e.toString(), e); } - bytePositions = new int[count]; // Trim to proper size - System.arraycopy(pos, 0, bytePositions, 0, count); + bytePositions = Arrays.copyOf(pos, count); // Trim to proper size /* * Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles. */ for (int i = 0; i < count; i++) { if (ihs[i] instanceof BranchHandle) { final BranchInstruction bi = (BranchInstruction) ihs[i].getInstruction(); - int target = bi.getPosition() + bi.getIndex(); - /* - * Byte code position: relative -> absolute. - */ + int target = bi.getPosition() + bi.getIndex(); /* + * Byte code position: relative -> absolute. + */ // Search for target position InstructionHandle ih = findHandle(ihs, pos, count, target); if (ih == null) { @@ -229,104 +173,59 @@ } /** - * Append another list after instruction (handle) ih contained in this list. - * Consumes argument list, i.e., it becomes empty. + * Initialize list with (nonnull) compound instruction. Consumes argument list, i.e., it becomes empty. * - * @param ih - * where to append the instruction list - * @param il - * Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction + * @param c compound instruction (list) */ - public InstructionHandle append(final InstructionHandle ih, final InstructionList il) { - if (il == null) { - throw new ClassGenException("Appending null InstructionList"); - } - if (il.isEmpty()) { - return ih; - } - final InstructionHandle next = ih.getNext(); - final InstructionHandle ret = il.start; - ih.setNext(il.start); - il.start.setPrev(ih); - il.end.setNext(next); - if (next != null) { - next.setPrev(il.end); - } else { - end = il.end; // Update end ... - } - length += il.length; // Update length - il.clear(); - return ret; + public InstructionList(final CompoundInstruction c) { + append(c.getInstructionList()); } /** - * Append another list after instruction i contained in this list. Consumes - * argument list, i.e., it becomes empty. + * Create instruction list containing one instruction. * - * @param i - * where to append the instruction list - * @param il - * Instruction list to append to this one - * @return instruction handle pointing to the first appended instruction + * @param i initial instruction */ - public InstructionHandle append(final Instruction i, final InstructionList il) { - InstructionHandle ih; - if ((ih = findInstruction2(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); + public InstructionList(final Instruction i) { + append(i); + } + + /** + * Add observer for this object. + */ + public void addObserver(final InstructionListObserver o) { + if (observers == null) { + observers = new ArrayList<>(); } - return append(ih, il); + observers.add(o); } /** - * Append another list to this one. Consumes argument list, i.e., it becomes - * empty. + * Append a branch instruction to the end of this list. * - * @param il - * list to append to end of this list - * @return instruction handle of the first appended instruction + * @param i branch instruction to append + * @return branch instruction handle of the appended instruction */ - public InstructionHandle append(final InstructionList il) { - if (il == null) { - throw new ClassGenException("Appending null InstructionList"); - } - if (il.isEmpty()) { - return null; - } - if (isEmpty()) { - start = il.start; - end = il.end; - length = il.length; - il.clear(); - return start; - } - return append(end, il); // was end.instruction + public BranchHandle append(final BranchInstruction i) { + final BranchHandle ih = BranchHandle.getBranchHandle(i); + append(ih); + return ih; } /** - * Append an instruction to the end of this list. + * Append a compound instruction. * - * @param ih - * instruction to append + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction */ - private void append(final InstructionHandle ih) { - if (isEmpty()) { - start = end = ih; - ih.setNext(ih.setPrev(null)); - } else { - end.setNext(ih); - ih.setPrev(end); - ih.setNext(null); - end = ih; - } - length++; // Update length + public InstructionHandle append(final CompoundInstruction c) { + return append(c.getInstructionList()); } /** * Append an instruction to the end of this list. * - * @param i - * instruction to append + * @param i instruction to append * @return instruction handle of the appended instruction */ public InstructionHandle append(final Instruction i) { @@ -336,26 +235,21 @@ } /** - * Append a branch instruction to the end of this list. + * Append a compound instruction, after instruction i. * - * @param i - * branch instruction to append - * @return branch instruction handle of the appended instruction + * @param i Instruction in list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first appended instruction */ - public BranchHandle append(final BranchInstruction i) { - final BranchHandle ih = BranchHandle.getBranchHandle(i); - append(ih); - return ih; + public InstructionHandle append(final Instruction i, final CompoundInstruction c) { + return append(i, c.getInstructionList()); } /** - * Append a single instruction j after another instruction i, which must be - * in this list of course! + * Append a single instruction j after another instruction i, which must be in this list of course! * - * @param i - * Instruction in list - * @param j - * Instruction to append after i in list + * @param i Instruction in list + * @param j Instruction to append after i in list * @return instruction handle of the first appended instruction */ public InstructionHandle append(final Instruction i, final Instruction j) { @@ -363,36 +257,58 @@ } /** - * Append a compound instruction, after instruction i. + * Append another list after instruction i contained in this list. Consumes argument list, i.e., it becomes empty. * - * @param i - * Instruction in list - * @param c - * The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction + * @param i where to append the instruction list + * @param il Instruction list to append to this one + * @return instruction handle pointing to the first appended instruction */ - public InstructionHandle append(final Instruction i, final CompoundInstruction c) { - return append(i, c.getInstructionList()); + public InstructionHandle append(final Instruction i, final InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction2(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + return append(ih, il); } /** - * Append a compound instruction. + * Append an instruction to the end of this list. * - * @param c - * The composite instruction (containing an InstructionList) - * @return instruction handle of the first appended instruction + * @param ih instruction to append */ - public InstructionHandle append(final CompoundInstruction c) { - return append(c.getInstructionList()); + private void append(final InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.setNext(ih.setPrev(null)); + } else { + end.setNext(ih); + ih.setPrev(end); + ih.setNext(null); + end = ih; + } + length++; // Update length + } + + /** + * Append an instruction after instruction (handle) ih contained in this list. + * + * @param ih where to append the instruction list + * @param i Instruction to append + * @return instruction handle pointing to the first appended instruction + */ + public BranchHandle append(final InstructionHandle ih, final BranchInstruction i) { + final BranchHandle bh = BranchHandle.getBranchHandle(i); + final InstructionList il = new InstructionList(); + il.append(bh); + append(ih, il); + return bh; } /** * Append a compound instruction. * - * @param ih - * where to append the instruction list - * @param c - * The composite instruction (containing an InstructionList) + * @param ih where to append the instruction list + * @param c The composite instruction (containing an InstructionList) * @return instruction handle of the first appended instruction */ public InstructionHandle append(final InstructionHandle ih, final CompoundInstruction c) { @@ -402,10 +318,8 @@ /** * Append an instruction after instruction (handle) ih contained in this list. * - * @param ih - * where to append the instruction list - * @param i - * Instruction to append + * @param ih where to append the instruction list + * @param i Instruction to append * @return instruction handle pointing to the first appended instruction */ public InstructionHandle append(final InstructionHandle ih, final Instruction i) { @@ -413,48 +327,29 @@ } /** - * Append an instruction after instruction (handle) ih contained in this list. + * Append another list after instruction (handle) ih contained in this list. Consumes argument list, i.e., it becomes + * empty. * - * @param ih - * where to append the instruction list - * @param i - * Instruction to append + * @param ih where to append the instruction list + * @param il Instruction list to append to this one * @return instruction handle pointing to the first appended instruction */ - public BranchHandle append(final InstructionHandle ih, final BranchInstruction i) { - final BranchHandle bh = BranchHandle.getBranchHandle(i); - final InstructionList il = new InstructionList(); - il.append(bh); - append(ih, il); - return bh; - } - - /** - * Insert another list before Instruction handle ih contained in this list. - * Consumes argument list, i.e., it becomes empty. - * - * @param ih - * where to append the instruction list - * @param il - * Instruction list to insert - * @return instruction handle of the first inserted instruction - */ - public InstructionHandle insert(final InstructionHandle ih, final InstructionList il) { + public InstructionHandle append(final InstructionHandle ih, final InstructionList il) { if (il == null) { - throw new ClassGenException("Inserting null InstructionList"); + throw new ClassGenException("Appending null InstructionList"); } if (il.isEmpty()) { return ih; } - final InstructionHandle prev = ih.getPrev(); + final InstructionHandle next = ih.getNext(); final InstructionHandle ret = il.start; - ih.setPrev(il.end); - il.end.setNext(ih); - il.start.setPrev(prev); - if (prev != null) { - prev.setNext(il.start); + ih.setNext(il.start); + il.start.setPrev(ih); + il.end.setNext(next); + if (next != null) { + next.setPrev(il.end); } else { - start = il.start; // Update start ... + end = il.end; // Update end ... } length += il.length; // Update length il.clear(); @@ -462,75 +357,296 @@ } /** - * Insert another list. + * Append another list to this one. Consumes argument list, i.e., it becomes empty. * - * @param il - * list to insert before start of this list - * @return instruction handle of the first inserted instruction + * @param il list to append to end of this list + * @return instruction handle of the first appended instruction */ - public InstructionHandle insert(final InstructionList il) { + public InstructionHandle append(final InstructionList il) { + if (il == null) { + throw new ClassGenException("Appending null InstructionList"); + } + if (il.isEmpty()) { + return null; + } if (isEmpty()) { - append(il); // Code is identical for this case + start = il.start; + end = il.end; + length = il.length; + il.clear(); return start; } - return insert(start, il); + return append(end, il); // was end.instruction } - /** - * Insert an instruction at start of this list. - * - * @param ih - * instruction to insert + private void clear() { + start = end = null; + length = 0; + } + + public boolean contains(final Instruction i) { + return findInstruction1(i) != null; + } + + public boolean contains(final InstructionHandle i) { + if (i == null) { + return false; + } + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + if (ih == i) { + return true; + } + } + return false; + } + + /** + * @return complete, i.e., deep copy of this list */ - private void insert(final InstructionHandle ih) { - if (isEmpty()) { - start = end = ih; - ih.setNext(ih.setPrev(null)); - } else { - start.setPrev(ih); - ih.setNext(start); - ih.setPrev(null); - start = ih; + public InstructionList copy() { + final Map map = new HashMap<>(); + final InstructionList il = new InstructionList(); + /* + * Pass 1: Make copies of all instructions, append them to the new list and associate old instruction references with + * the new ones, i.e., a 1:1 mapping. + */ + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + final Instruction c = i.copy(); // Use clone for shallow copy + if (c instanceof BranchInstruction) { + map.put(ih, il.append((BranchInstruction) c)); + } else { + map.put(ih, il.append(c)); + } } - length++; + /* + * Pass 2: Update branch targets. + */ + InstructionHandle ih = start; + InstructionHandle ch = il.start; + while (ih != null) { + final Instruction i = ih.getInstruction(); + final Instruction c = ch.getInstruction(); + if (i instanceof BranchInstruction) { + final BranchInstruction bi = (BranchInstruction) i; + final BranchInstruction bc = (BranchInstruction) c; + final InstructionHandle itarget = bi.getTarget(); // old target + // New target is in hash map + bc.setTarget(map.get(itarget)); + if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final InstructionHandle[] itargets = ((Select) bi).getTargets(); + final InstructionHandle[] ctargets = ((Select) bc).getTargets(); + for (int j = 0; j < itargets.length; j++) { // Update all targets + ctargets[j] = map.get(itargets[j]); + } + } + } + ih = ih.getNext(); + ch = ch.getNext(); + } + return il; } /** - * Insert another list before Instruction i contained in this list. Consumes - * argument list, i.e., it becomes empty. + * Remove instruction from this list. The corresponding Instruction handles must not be reused! * - * @param i - * where to append the instruction list - * @param il - * Instruction list to insert - * @return instruction handle pointing to the first inserted instruction, i.e., il.getStart() + * @param i instruction to remove */ - public InstructionHandle insert(final Instruction i, final InstructionList il) { + public void delete(final Instruction i) throws TargetLostException { InstructionHandle ih; if ((ih = findInstruction1(i)) == null) { throw new ClassGenException("Instruction " + i + " is not contained in this list."); } - return insert(ih, il); + delete(ih); } /** - * Insert an instruction at start of this list. + * Remove instructions from instruction 'from' to instruction 'to' contained in this list. The user must ensure that + * 'from' is an instruction before 'to', or risk havoc. The corresponding Instruction handles must not be reused! * - * @param i - * instruction to insert - * @return instruction handle of the inserted instruction + * @param from where to start deleting (inclusive) + * @param to where to end deleting (inclusive) */ - public InstructionHandle insert(final Instruction i) { - final InstructionHandle ih = InstructionHandle.getInstructionHandle(i); - insert(ih); - return ih; + public void delete(final Instruction from, final Instruction to) throws TargetLostException { + InstructionHandle fromIh; + InstructionHandle toIh; + if ((fromIh = findInstruction1(from)) == null) { + throw new ClassGenException("Instruction " + from + " is not contained in this list."); + } + if ((toIh = findInstruction2(to)) == null) { + throw new ClassGenException("Instruction " + to + " is not contained in this list."); + } + delete(fromIh, toIh); + } + + /** + * Remove instruction from this list. The corresponding Instruction handles must not be reused! + * + * @param ih instruction (handle) to remove + */ + public void delete(final InstructionHandle ih) throws TargetLostException { + remove(ih.getPrev(), ih.getNext()); + } + + /** + * Remove instructions from instruction 'from' to instruction 'to' contained in this list. The user must ensure that + * 'from' is an instruction before 'to', or risk havoc. The corresponding Instruction handles must not be reused! + * + * @param from where to start deleting (inclusive) + * @param to where to end deleting (inclusive) + */ + public void delete(final InstructionHandle from, final InstructionHandle to) throws TargetLostException { + remove(from.getPrev(), to.getNext()); + } + + /** + * Delete contents of list. Provides better memory utilization, because the system then may reuse the instruction + * handles. This method is typically called right after {@link MethodGen#getMethod()}. + */ + public void dispose() { + // Traverse in reverse order, because ih.next is overwritten + for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { + // Causes BranchInstructions to release target and targeters, because it calls dispose() on the contained instruction. + ih.dispose(); + } + clear(); + } + + /** + * Get instruction handle for instruction at byte code position pos. This only works properly, if the list is freshly + * initialized from a byte array or setPositions() has been called before this method. + * + * @param pos byte code position to search for + * @return target position's instruction handle if available + */ + public InstructionHandle findHandle(final int pos) { + final int[] positions = bytePositions; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + if (positions[i] == pos) { + return ih; + } + ih = ih.getNext(); + } + return null; + } + + /** + * Search for given Instruction reference, start at beginning of list. + * + * @param i instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction1(final Instruction i) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + if (ih.getInstruction() == i) { + return ih; + } + } + return null; + } + + /** + * Search for given Instruction reference, start at end of list + * + * @param i instruction to search for + * @return instruction found on success, null otherwise + */ + private InstructionHandle findInstruction2(final Instruction i) { + for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { + if (ih.getInstruction() == i) { + return ih; + } + } + return null; + } + + /** + * When everything is finished, use this method to convert the instruction list into an array of bytes. + * + * @return the byte code ready to be dumped + */ + public byte[] getByteCode() { + // Update position indices of instructions + setPositions(); + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + final DataOutputStream out = new DataOutputStream(b); + try { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + i.dump(out); // Traverse list + } + out.flush(); + } catch (final IOException e) { + System.err.println(e); + return Const.EMPTY_BYTE_ARRAY; + } + return b.toByteArray(); + } + + /** + * @return end of list + */ + public InstructionHandle getEnd() { + return end; + } + + /** + * @return array containing all instructions (handles) + */ + public InstructionHandle[] getInstructionHandles() { + final InstructionHandle[] ihs = new InstructionHandle[length]; + InstructionHandle ih = start; + for (int i = 0; i < length; i++) { + ihs[i] = ih; + ih = ih.getNext(); + } + return ihs; + } + + /** + * Get positions (offsets) of all instructions in the list. This relies on that the list has been freshly created from + * an byte code array, or that setPositions() has been called. Otherwise this may be inaccurate. + * + * @return array containing all instruction's offset in byte code + */ + public int[] getInstructionPositions() { + return bytePositions; + } + + /** + * @return an array of instructions without target information for branch instructions. + */ + public Instruction[] getInstructions() { + final List instructions = new ArrayList<>(); + try (ByteSequence bytes = new ByteSequence(getByteCode())) { + while (bytes.available() > 0) { + instructions.add(Instruction.readInstruction(bytes)); + } + } catch (final IOException e) { + throw new ClassGenException(e.toString(), e); + } + return instructions.toArray(Instruction.EMPTY_ARRAY); + } + + /** + * @return length of list (Number of instructions, not bytes) + */ + public int getLength() { + return length; + } + + /** + * @return start of list + */ + public InstructionHandle getStart() { + return start; } /** * Insert a branch instruction at start of this list. * - * @param i - * branch instruction to insert + * @param i branch instruction to insert * @return branch instruction handle of the appended instruction */ public BranchHandle insert(final BranchInstruction i) { @@ -540,26 +656,32 @@ } /** - * Insert a single instruction j before another instruction i, which must be - * in this list of course! + * Insert a compound instruction. * - * @param i - * Instruction in list - * @param j - * Instruction to insert before i in list + * @param c The composite instruction (containing an InstructionList) * @return instruction handle of the first inserted instruction */ - public InstructionHandle insert(final Instruction i, final Instruction j) { - return insert(i, new InstructionList(j)); + public InstructionHandle insert(final CompoundInstruction c) { + return insert(c.getInstructionList()); + } + + /** + * Insert an instruction at start of this list. + * + * @param i instruction to insert + * @return instruction handle of the inserted instruction + */ + public InstructionHandle insert(final Instruction i) { + final InstructionHandle ih = InstructionHandle.getInstructionHandle(i); + insert(ih); + return ih; } /** * Insert a compound instruction before instruction i. * - * @param i - * Instruction in list - * @param c - * The composite instruction (containing an InstructionList) + * @param i Instruction in list + * @param c The composite instruction (containing an InstructionList) * @return instruction handle of the first inserted instruction */ public InstructionHandle insert(final Instruction i, final CompoundInstruction c) { @@ -567,49 +689,54 @@ } /** - * Insert a compound instruction. + * Insert a single instruction j before another instruction i, which must be in this list of course! * - * @param c - * The composite instruction (containing an InstructionList) + * @param i Instruction in list + * @param j Instruction to insert before i in list * @return instruction handle of the first inserted instruction */ - public InstructionHandle insert(final CompoundInstruction c) { - return insert(c.getInstructionList()); + public InstructionHandle insert(final Instruction i, final Instruction j) { + return insert(i, new InstructionList(j)); } /** - * Insert an instruction before instruction (handle) ih contained in this list. + * Insert another list before Instruction i contained in this list. Consumes argument list, i.e., it becomes empty. * - * @param ih - * where to insert to the instruction list - * @param i - * Instruction to insert - * @return instruction handle of the first inserted instruction + * @param i where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle pointing to the first inserted instruction, i.e., il.getStart() */ - public InstructionHandle insert(final InstructionHandle ih, final Instruction i) { - return insert(ih, new InstructionList(i)); + public InstructionHandle insert(final Instruction i, final InstructionList il) { + InstructionHandle ih; + if ((ih = findInstruction1(i)) == null) { + throw new ClassGenException("Instruction " + i + " is not contained in this list."); + } + return insert(ih, il); } /** - * Insert a compound instruction. + * Insert an instruction at start of this list. * - * @param ih - * where to insert the instruction list - * @param c - * The composite instruction (containing an InstructionList) - * @return instruction handle of the first inserted instruction + * @param ih instruction to insert */ - public InstructionHandle insert(final InstructionHandle ih, final CompoundInstruction c) { - return insert(ih, c.getInstructionList()); + private void insert(final InstructionHandle ih) { + if (isEmpty()) { + start = end = ih; + ih.setNext(ih.setPrev(null)); + } else { + start.setPrev(ih); + ih.setNext(start); + ih.setPrev(null); + start = ih; + } + length++; } /** * Insert an instruction before instruction (handle) ih contained in this list. * - * @param ih - * where to insert to the instruction list - * @param i - * Instruction to insert + * @param ih where to insert to the instruction list + * @param i Instruction to insert * @return instruction handle of the first inserted instruction */ public BranchHandle insert(final InstructionHandle ih, final BranchInstruction i) { @@ -621,33 +748,144 @@ } /** - * Take all instructions (handles) from "start" to "end" and append them - * after the new location "target". Of course, "end" must be after "start" - * and target must not be located within this range. If you want to move - * something to the start of the list use null as value for target. + * Insert a compound instruction. + * + * @param ih where to insert the instruction list + * @param c The composite instruction (containing an InstructionList) + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final CompoundInstruction c) { + return insert(ih, c.getInstructionList()); + } + + /** + * Insert an instruction before instruction (handle) ih contained in this list. + * + * @param ih where to insert to the instruction list + * @param i Instruction to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final Instruction i) { + return insert(ih, new InstructionList(i)); + } + + /** + * Insert another list before Instruction handle ih contained in this list. Consumes argument list, i.e., it becomes + * empty. + * + * @param ih where to append the instruction list + * @param il Instruction list to insert + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionHandle ih, final InstructionList il) { + if (il == null) { + throw new ClassGenException("Inserting null InstructionList"); + } + if (il.isEmpty()) { + return ih; + } + final InstructionHandle prev = ih.getPrev(); + final InstructionHandle ret = il.start; + ih.setPrev(il.end); + il.end.setNext(ih); + il.start.setPrev(prev); + if (prev != null) { + prev.setNext(il.start); + } else { + start = il.start; // Update start ... + } + length += il.length; // Update length + il.clear(); + return ret; + } + + /** + * Insert another list. + * + * @param il list to insert before start of this list + * @return instruction handle of the first inserted instruction + */ + public InstructionHandle insert(final InstructionList il) { + if (isEmpty()) { + append(il); // Code is identical for this case + return start; + } + return insert(start, il); + } + + /** + * Test for empty list. + */ + public boolean isEmpty() { + return start == null; + } // && end == null + + /** + * @return iterator that lists all instructions (handles) + */ + @Override + public Iterator iterator() { + return new Iterator() { + + private InstructionHandle ih = start; + + @Override + public boolean hasNext() { + return ih != null; + } + + @Override + public InstructionHandle next() throws NoSuchElementException { + if (ih == null) { + throw new NoSuchElementException(); + } + final InstructionHandle i = ih; + ih = ih.getNext(); + return i; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + /** + * Move a single instruction (handle) to a new location. + * + * @param ih moved instruction + * @param target new location of moved instruction + */ + public void move(final InstructionHandle ih, final InstructionHandle target) { + move(ih, ih, target); + } + + /** + * Take all instructions (handles) from "start" to "end" and append them after the new location "target". Of course, + * "end" must be after "start" and target must not be located withing this range. If you want to move something to the + * start of the list use null as value for target. *

    - * Any instruction targeters pointing to handles within the block, keep - * their targets. + * Any instruction targeters pointing to handles within the block, keep their targets. + *

    * - * @param start - * of moved block - * @param end - * of moved block - * @param target - * of moved block + * @param start of moved block + * @param end of moved block + * @param target of moved block */ public void move(final InstructionHandle start, final InstructionHandle end, final InstructionHandle target) { // Step 1: Check constraints - if ((start == null) || (end == null)) { + if (start == null || end == null) { throw new ClassGenException("Invalid null handle: From " + start + " to " + end); } - if ((target == start) || (target == end)) { + if (target == start || target == end) { throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); } for (InstructionHandle ih = start; ih != end.getNext(); ih = ih.getNext()) { if (ih == null) { throw new ClassGenException("Invalid range: From " + start + " to " + end); - } else if (ih == target) { + } + if (ih == target) { throw new ClassGenException("Invalid range: From " + start + " to " + end + " contains target " + target); } } @@ -686,31 +924,86 @@ } /** - * Move a single instruction (handle) to a new location. + * Redirect all references from oldTarget to newTarget, i.e., update targets of branch instructions. * - * @param ih - * moved instruction - * @param target - * new location of moved instruction + * @param oldTarget the old target instruction handle + * @param newTarget the new target instruction handle */ - public void move(final InstructionHandle ih, final InstructionHandle target) { - move(ih, ih, target); + public void redirectBranches(final InstructionHandle oldTarget, final InstructionHandle newTarget) { + for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { + final Instruction i = ih.getInstruction(); + if (i instanceof BranchInstruction) { + final BranchInstruction b = (BranchInstruction) i; + final InstructionHandle target = b.getTarget(); + if (target == oldTarget) { + b.setTarget(newTarget); + } + if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH + final InstructionHandle[] targets = ((Select) b).getTargets(); + for (int j = 0; j < targets.length; j++) { + if (targets[j] == oldTarget) { + ((Select) b).setTarget(j, newTarget); + } + } + } + } + } + } + + /** + * Redirect all references of exception handlers from oldTarget to newTarget. + * + * @param exceptions array of exception handlers + * @param oldTarget the old target instruction handle + * @param newTarget the new target instruction handle + * @see MethodGen + */ + public void redirectExceptionHandlers(final CodeExceptionGen[] exceptions, final InstructionHandle oldTarget, final InstructionHandle newTarget) { + for (final CodeExceptionGen exception : exceptions) { + if (exception.getStartPC() == oldTarget) { + exception.setStartPC(newTarget); + } + if (exception.getEndPC() == oldTarget) { + exception.setEndPC(newTarget); + } + if (exception.getHandlerPC() == oldTarget) { + exception.setHandlerPC(newTarget); + } + } } /** - * Remove from instruction `prev' to instruction `next' both contained in - * this list. Throws TargetLostException when one of the removed instruction - * handles is still being targeted. - * - * @param prev - * where to start deleting (predecessor, exclusive) - * @param next - * where to end deleting (successor, exclusive) + * Redirect all references of local variables from oldTarget to newTarget. + * + * @param lg array of local variables + * @param oldTarget the old target instruction handle + * @param newTarget the new target instruction handle + * @see MethodGen + */ + public void redirectLocalVariables(final LocalVariableGen[] lg, final InstructionHandle oldTarget, final InstructionHandle newTarget) { + for (final LocalVariableGen element : lg) { + final InstructionHandle start = element.getStart(); + final InstructionHandle end = element.getEnd(); + if (start == oldTarget) { + element.setStart(newTarget); + } + if (end == oldTarget) { + element.setEnd(newTarget); + } + } + } + + /** + * Remove from instruction 'prev' to instruction 'next' both contained in this list. Throws TargetLostException when one + * of the removed instruction handles is still being targeted. + * + * @param prev where to start deleting (predecessor, exclusive) + * @param next where to end deleting (successor, exclusive) */ private void remove(final InstructionHandle prev, InstructionHandle next) throws TargetLostException { InstructionHandle first; InstructionHandle last; // First and last deleted instruction - if ((prev == null) && (next == null)) { + if (prev == null && next == null) { first = start; last = end; start = end = null; @@ -732,7 +1025,7 @@ } first.setPrev(null); // Completely separated from rest of list last.setNext(null); - final List target_vec = new ArrayList<>(); + final List targetList = new ArrayList<>(); for (InstructionHandle ih = first; ih != null; ih = ih.getNext()) { ih.getInstruction().dispose(); // e.g. BranchInstructions release their targets } @@ -741,7 +1034,7 @@ next = ih.getNext(); length--; if (ih.hasTargeters()) { // Still got targeters? - target_vec.add(ih); + targetList.add(ih); buf.append(ih.toString(true)).append(" "); ih.setNext(ih.setPrev(null)); } else { @@ -749,120 +1042,32 @@ } } buf.append("}"); - if (!target_vec.isEmpty()) { - final InstructionHandle[] targeted = new InstructionHandle[target_vec.size()]; - target_vec.toArray(targeted); - throw new TargetLostException(targeted, buf.toString()); - } - } - - /** - * Remove instruction from this list. The corresponding Instruction handles - * must not be reused! - * - * @param ih - * instruction (handle) to remove - */ - public void delete(final InstructionHandle ih) throws TargetLostException { - remove(ih.getPrev(), ih.getNext()); - } - - /** - * Remove instruction from this list. The corresponding Instruction handles must not be reused! - * - * @param i - * instruction to remove - */ - public void delete(final Instruction i) throws TargetLostException { - InstructionHandle ih; - if ((ih = findInstruction1(i)) == null) { - throw new ClassGenException("Instruction " + i + " is not contained in this list."); + if (!targetList.isEmpty()) { + throw new TargetLostException(targetList.toArray(InstructionHandle.EMPTY_ARRAY), buf.toString()); } - delete(ih); } /** - * Remove instructions from instruction `from' to instruction `to' contained - * in this list. The user must ensure that `from' is an instruction before - * `to', or risk havoc. The corresponding Instruction handles must not be - * reused! - * - * @param from - * where to start deleting (inclusive) - * @param to - * where to end deleting (inclusive) - */ - public void delete(final InstructionHandle from, final InstructionHandle to) throws TargetLostException { - remove(from.getPrev(), to.getNext()); - } - - /** - * Remove instructions from instruction `from' to instruction `to' contained in this list. The user must ensure that `from' is an instruction before `to', - * or risk havoc. The corresponding Instruction handles must not be reused! - * - * @param from - * where to start deleting (inclusive) - * @param to - * where to end deleting (inclusive) - */ - public void delete(final Instruction from, final Instruction to) throws TargetLostException { - InstructionHandle from_ih; - InstructionHandle to_ih; - if ((from_ih = findInstruction1(from)) == null) { - throw new ClassGenException("Instruction " + from + " is not contained in this list."); - } - if ((to_ih = findInstruction2(to)) == null) { - throw new ClassGenException("Instruction " + to + " is not contained in this list."); - } - delete(from_ih, to_ih); - } - - /** - * Search for given Instruction reference, start at beginning of list. - * - * @param i - * instruction to search for - * @return instruction found on success, null otherwise + * Remove observer for this object. */ - private InstructionHandle findInstruction1(final Instruction i) { - for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - if (ih.getInstruction() == i) { - return ih; - } + public void removeObserver(final InstructionListObserver o) { + if (observers != null) { + observers.remove(o); } - return null; } /** - * Search for given Instruction reference, start at end of list - * - * @param i - * instruction to search for - * @return instruction found on success, null otherwise + * Replace all references to the old constant pool with references to the new constant pool */ - private InstructionHandle findInstruction2(final Instruction i) { - for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { - if (ih.getInstruction() == i) { - return ih; - } - } - return null; - } - - public boolean contains(final InstructionHandle i) { - if (i == null) { - return false; - } + public void replaceConstantPool(final ConstantPoolGen oldCp, final ConstantPoolGen newCp) { for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - if (ih == i) { - return true; + final Instruction i = ih.getInstruction(); + if (i instanceof CPInstruction) { + final CPInstruction ci = (CPInstruction) i; + final Constant c = oldCp.getConstant(ci.getIndex()); + ci.setIndex(newCp.addConstant(c, oldCp)); } } - return false; - } - - public boolean contains(final Instruction i) { - return findInstruction1(i) != null; } public void setPositions() { // TODO could be package-protected? (some test code would need to be repackaged) @@ -870,15 +1075,13 @@ } /** - * Give all instructions their position number (offset in byte stream), - * i.e., make the list ready to be dumped. + * Give all instructions their position number (offset in byte stream), i.e., make the list ready to be dumped. * - * @param check - * Perform sanity checks, e.g. if all targeted instructions really belong to this list + * @param check Perform sanity checks, e.g. if all targeted instructions really belong to this list */ public void setPositions(final boolean check) { // called by code in other packages - int max_additional_bytes = 0; - int additional_bytes = 0; + int maxAdditionalBytes = 0; + int additionalBytes = 0; int index = 0; int count = 0; final int[] pos = new int[length]; @@ -891,26 +1094,20 @@ if (i instanceof BranchInstruction) { // target instruction within list? Instruction inst = ((BranchInstruction) i).getTarget().getInstruction(); if (!contains(inst)) { - throw new ClassGenException("Branch target of " - + Const.getOpcodeName(i.getOpcode()) + ":" - + inst + " not in instruction list"); + throw new ClassGenException("Branch target of " + Const.getOpcodeName(i.getOpcode()) + ":" + inst + " not in instruction list"); } if (i instanceof Select) { final InstructionHandle[] targets = ((Select) i).getTargets(); for (final InstructionHandle target : targets) { inst = target.getInstruction(); if (!contains(inst)) { - throw new ClassGenException("Branch target of " - + Const.getOpcodeName(i.getOpcode()) + ":" - + inst + " not in instruction list"); + throw new ClassGenException("Branch target of " + Const.getOpcodeName(i.getOpcode()) + ":" + inst + " not in instruction list"); } } } if (!(ih instanceof BranchHandle)) { throw new ClassGenException( - "Branch instruction " - + Const.getOpcodeName(i.getOpcode()) + ":" - + inst + " not contained in BranchHandle."); + "Branch instruction " + Const.getOpcodeName(i.getOpcode()) + ":" + inst + " not contained in BranchHandle."); } } } @@ -923,33 +1120,30 @@ ih.setPosition(index); pos[count++] = index; /* - * Get an estimate about how many additional bytes may be added, - * because BranchInstructions may have variable length depending on the target offset - * (short vs. int) or alignment issues (TABLESWITCH and LOOKUPSWITCH). + * Get an estimate about how many additional bytes may be added, because BranchInstructions may have variable length + * depending on the target offset (short vs. int) or alignment issues (TABLESWITCH and LOOKUPSWITCH). */ switch (i.getOpcode()) { - case Const.JSR: - case Const.GOTO: - max_additional_bytes += 2; + case Const.JSR: + case Const.GOTO: + maxAdditionalBytes += 2; break; - case Const.TABLESWITCH: - case Const.LOOKUPSWITCH: - max_additional_bytes += 3; + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: + maxAdditionalBytes += 3; break; } index += i.getLength(); } - - /* Pass 2: Expand the variable-length (Branch)Instructions depending on - * the target offset (short or int) and ensure that branch targets are - * within this list. + /* + * Pass 2: Expand the variable-length (Branch)Instructions depending on the target offset (short or int) and ensure that + * branch targets are within this list. */ for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - additional_bytes += ih.updatePosition(additional_bytes, max_additional_bytes); + additionalBytes += ih.updatePosition(additionalBytes, maxAdditionalBytes); } /* - * Pass 3: Update position numbers (which may have changed due to the - * preceding expansions), like pass 1. + * Pass 3: Update position numbers (which may have changed due to the preceding expansions), like pass 1. */ index = count = 0; for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { @@ -963,43 +1157,10 @@ } /** - * When everything is finished, use this method to convert the instruction - * list into an array of bytes. - * - * @return the byte code ready to be dumped - */ - public byte[] getByteCode() { - // Update position indices of instructions - setPositions(); - final ByteArrayOutputStream b = new ByteArrayOutputStream(); - final DataOutputStream out = new DataOutputStream(b); - try { - for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - final Instruction i = ih.getInstruction(); - i.dump(out); // Traverse list - } - out.flush(); - } catch (final IOException e) { - System.err.println(e); - return new byte[0]; - } - return b.toByteArray(); - } - - /** - * @return an array of instructions without target information for branch - * instructions. + * @return length of list (Number of instructions, not bytes) */ - public Instruction[] getInstructions() { - final List instructions = new ArrayList<>(); - try (ByteSequence bytes = new ByteSequence(getByteCode())) { - while (bytes.available() > 0) { - instructions.add(Instruction.readInstruction(bytes)); - } - } catch (final IOException e) { - throw new ClassGenException(e.toString(), e); - } - return instructions.toArray(new Instruction[instructions.size()]); + public int size() { + return length; } @Override @@ -1008,8 +1169,7 @@ } /** - * @param verbose - * toggle output format + * @param verbose toggle output format * @return String containing all instructions in this list. */ public String toString(final boolean verbose) { @@ -1021,277 +1181,8 @@ } /** - * @return iterator that lists all instructions (handles) - */ - @Override - public Iterator iterator() { - return new Iterator() { - - private InstructionHandle ih = start; - - @Override - public InstructionHandle next() throws NoSuchElementException { - if (ih == null) { - throw new NoSuchElementException(); - } - final InstructionHandle i = ih; - ih = ih.getNext(); - return i; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean hasNext() { - return ih != null; - } - }; - } - - /** - * @return array containing all instructions (handles) - */ - public InstructionHandle[] getInstructionHandles() { - final InstructionHandle[] ihs = new InstructionHandle[length]; - InstructionHandle ih = start; - for (int i = 0; i < length; i++) { - ihs[i] = ih; - ih = ih.getNext(); - } - return ihs; - } - - /** - * Get positions (offsets) of all instructions in the list. This relies on - * that the list has been freshly created from an byte code array, or that - * setPositions() has been called. Otherwise this may be inaccurate. - * - * @return array containing all instruction's offset in byte code - */ - public int[] getInstructionPositions() { - return bytePositions; - } - - /** - * @return complete, i.e., deep copy of this list - */ - public InstructionList copy() { - final Map map = new HashMap<>(); - final InstructionList il = new InstructionList(); - /* - * Pass 1: Make copies of all instructions, append them to the new list - * and associate old instruction references with the new ones, i.e., a 1:1 mapping. - */ - for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - final Instruction i = ih.getInstruction(); - final Instruction c = i.copy(); // Use clone for shallow copy - if (c instanceof BranchInstruction) { - map.put(ih, il.append((BranchInstruction) c)); - } else { - map.put(ih, il.append(c)); - } - } - /* - * Pass 2: Update branch targets. - */ - InstructionHandle ih = start; - InstructionHandle ch = il.start; - while (ih != null) { - final Instruction i = ih.getInstruction(); - final Instruction c = ch.getInstruction(); - if (i instanceof BranchInstruction) { - final BranchInstruction bi = (BranchInstruction) i; - final BranchInstruction bc = (BranchInstruction) c; - final InstructionHandle itarget = bi.getTarget(); // old target - // New target is in hash map - bc.setTarget(map.get(itarget)); - if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - final InstructionHandle[] itargets = ((Select) bi).getTargets(); - final InstructionHandle[] ctargets = ((Select) bc).getTargets(); - for (int j = 0; j < itargets.length; j++) { // Update all targets - ctargets[j] = map.get(itargets[j]); - } - } - } - ih = ih.getNext(); - ch = ch.getNext(); - } - return il; - } - - /** - * Replace all references to the old constant pool with references to the - * new constant pool - */ - public void replaceConstantPool(final ConstantPoolGen old_cp, final ConstantPoolGen new_cp) { - for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - final Instruction i = ih.getInstruction(); - if (i instanceof CPInstruction) { - final CPInstruction ci = (CPInstruction) i; - final Constant c = old_cp.getConstant(ci.getIndex()); - ci.setIndex(new_cp.addConstant(c, old_cp)); - } - } - } - - private void clear() { - start = end = null; - length = 0; - } - - /** - * Delete contents of list. Provides better memory utilization, because the - * system then may reuse the instruction handles. This method is typically - * called right after {@link MethodGen#getMethod()}. - */ - public void dispose() { - // Traverse in reverse order, because ih.next is overwritten - for (InstructionHandle ih = end; ih != null; ih = ih.getPrev()) { - /* - * Causes BranchInstructions to release target and targeters, - * because it calls dispose() on the contained instruction. - */ - ih.dispose(); - } - clear(); - } - - /** - * @return start of list - */ - public InstructionHandle getStart() { - return start; - } - - /** - * @return end of list - */ - public InstructionHandle getEnd() { - return end; - } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int getLength() { - return length; - } - - /** - * @return length of list (Number of instructions, not bytes) - */ - public int size() { - return length; - } - - /** - * Redirect all references from old_target to new_target, i.e., update - * targets of branch instructions. - * - * @param old_target - * the old target instruction handle - * @param new_target - * the new target instruction handle - */ - public void redirectBranches(final InstructionHandle old_target, final InstructionHandle new_target) { - for (InstructionHandle ih = start; ih != null; ih = ih.getNext()) { - final Instruction i = ih.getInstruction(); - if (i instanceof BranchInstruction) { - final BranchInstruction b = (BranchInstruction) i; - final InstructionHandle target = b.getTarget(); - if (target == old_target) { - b.setTarget(new_target); - } - if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH - final InstructionHandle[] targets = ((Select) b).getTargets(); - for (int j = 0; j < targets.length; j++) { - if (targets[j] == old_target) { - ((Select) b).setTarget(j, new_target); - } - } - } - } - } - } - - /** - * Redirect all references of local variables from old_target to new_target. - * - * @param lg - * array of local variables - * @param old_target - * the old target instruction handle - * @param new_target - * the new target instruction handle - * @see MethodGen - */ - public void redirectLocalVariables(final LocalVariableGen[] lg, final InstructionHandle old_target, final InstructionHandle new_target) { - for (final LocalVariableGen element : lg) { - final InstructionHandle start = element.getStart(); - final InstructionHandle end = element.getEnd(); - if (start == old_target) { - element.setStart(new_target); - } - if (end == old_target) { - element.setEnd(new_target); - } - } - } - - /** - * Redirect all references of exception handlers from old_target to new_target. - * - * @param exceptions - * array of exception handlers - * @param old_target - * the old target instruction handle - * @param new_target - * the new target instruction handle - * @see MethodGen - */ - public void redirectExceptionHandlers(final CodeExceptionGen[] exceptions, - final InstructionHandle old_target, final InstructionHandle new_target) { - for (final CodeExceptionGen exception : exceptions) { - if (exception.getStartPC() == old_target) { - exception.setStartPC(new_target); - } - if (exception.getEndPC() == old_target) { - exception.setEndPC(new_target); - } - if (exception.getHandlerPC() == old_target) { - exception.setHandlerPC(new_target); - } - } - } - - private List observers; - - /** - * Add observer for this object. - */ - public void addObserver(final InstructionListObserver o) { - if (observers == null) { - observers = new ArrayList<>(); - } - observers.add(o); - } - - /** - * Remove observer for this object. - */ - public void removeObserver(final InstructionListObserver o) { - if (observers != null) { - observers.remove(o); - } - } - - /** - * Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be called by the - * user after he has finished editing the object. + * Call notify() method on all observers. This method is not called automatically whenever the state has changed, but + * has to be called by the user after he has finished editing the object. */ public void update() { if (observers != null) { diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionListObserver.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,11 +22,10 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Implement this interface if you're interested in changes to an InstructionList object - * and register yourself with addObserver(). - * + * Implement this interface if you're interested in changes to an InstructionList object and register yourself with + * addObserver(). */ public interface InstructionListObserver { - void notify( InstructionList list ); + void notify(InstructionList list); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InstructionTargeter.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,8 +22,7 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denote that a class targets InstructionHandles within an InstructionList. Namely - * the following implementers: + * Denote that a class targets InstructionHandles within an InstructionList. Namely the following implementers: * * @see BranchHandle * @see LocalVariableGen @@ -31,6 +30,8 @@ */ public interface InstructionTargeter { + // static final InstructionTargeter[] EMPTY_ARRAY = new InstructionTargeter[0]; + /** * Checks whether this targeter targets the specified instruction handle. */ @@ -39,9 +40,9 @@ /** * Replaces the target of this targeter from this old handle to the new handle. * - * @param old_ih the old handle - * @param new_ih the new handle - * @throws ClassGenException if old_ih is not targeted by this object + * @param oldIh the old handle + * @param newIh the new handle + * @throws ClassGenException if oldIh is not targeted by this object */ - void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) throws ClassGenException; + void updateTarget(InstructionHandle oldIh, InstructionHandle newIh) throws ClassGenException; } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEDYNAMIC.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,85 +31,34 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; /** - * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class - * expects to be able to get the class of the method. Ignores the bootstrap - * mechanism entirely. + * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class expects to be able to get the class + * of the method. Ignores the bootstrap mechanism entirely. * - * @see - * - * The invokedynamic instruction in The Java Virtual Machine Specification + * @see The + * invokedynamic instruction in The Java Virtual Machine Specification * @since 6.0 - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public class INVOKEDYNAMIC extends InvokeInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ INVOKEDYNAMIC() { } - public INVOKEDYNAMIC(final int index) { super(Const.INVOKEDYNAMIC, index); } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - out.writeShort(super.getIndex()); - out.writeByte(0); - out.writeByte(0); - } - - - /** - * Read needed data (i.e., index) from file. - */ - @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - super.initFromFile(bytes, wide); - super.setLength(5); - bytes.readByte(); // Skip 0 byte - bytes.readByte(); // Skip 0 byte - } - - - /** - * @return mnemonic for instruction with symbolic references resolved - */ - @Override - public String toString( final ConstantPool cp ) { - return super.toString(cp); - } - - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, - ExceptionConst.UNSATISFIED_LINK_ERROR, - ExceptionConst.ABSTRACT_METHOD_ERROR, - ExceptionConst.ILLEGAL_ACCESS_ERROR, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); @@ -122,28 +71,43 @@ } /** - * Override the parent method because our classname is held elsewhere. + * Dump instruction as byte code to stream out. * - * @param cpg the ConstantPool generator - * @deprecated in FieldOrMethod + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(0); + out.writeByte(0); + } + + /** + * Override the parent method because our class name is held elsewhere. * - * @return name of the referenced class/interface + * Note: Contrary to this method's name it does not return the class name of the invoke target; rather it returns the + * name of the method that will be used to invoke the Lambda method generated by this invoke dynamic instruction. */ @Override @Deprecated public String getClassName( final ConstantPoolGen cpg ) { final ConstantPool cp = cpg.getConstantPool(); - final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic); - return ((ConstantNameAndType) cp.getConstant(cid.getNameAndTypeIndex())).getName(cp); + final ConstantInvokeDynamic cid = cp.getConstant(super.getIndex(), Const.CONSTANT_InvokeDynamic, ConstantInvokeDynamic.class); + return cp.getConstant(cid.getNameAndTypeIndex(), ConstantNameAndType.class).getName(cp); } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, ExceptionConst.ILLEGAL_ACCESS_ERROR, ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } /** - * Since InvokeDynamic doesn't refer to a reference type, just return java.lang.Object, - * as that is the only type we can say for sure the reference will be. + * Since InvokeDynamic doesn't refer to a reference type, just return java.lang.Object, as that is the only type we can + * say for sure the reference will be. * - * @param cpg - * the ConstantPoolGen used to create the instruction + * @param cpg the ConstantPoolGen used to create the instruction * @return an ObjectType for java.lang.Object * @since 6.1 */ @@ -151,4 +115,16 @@ public ReferenceType getReferenceType(final ConstantPoolGen cpg) { return new ObjectType(Object.class.getName()); } + + /** + * Read needed data (i.e., index) from file. + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.initFromFile(bytes, wide); + super.setLength(5); + bytes.readByte(); // Skip 0 byte + bytes.readByte(); // Skip 0 byte + } + } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/InvokeInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,23 +26,21 @@ import com.sun.org.apache.bcel.internal.classfile.Constant; import com.sun.org.apache.bcel.internal.classfile.ConstantCP; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Super class for the INVOKExxx family of instructions. * - * @LastModified: Jan 2020 + * @LastModified: Feb 2023 */ -public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower, - StackConsumer, StackProducer { +public abstract class InvokeInstruction extends FieldOrMethod implements ExceptionThrower, StackConsumer, StackProducer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ InvokeInstruction() { } - /** * @param index to constant pool */ @@ -50,39 +48,15 @@ super(opcode, index); } - /** - * @return mnemonic for instruction with symbolic references resolved - */ - @Override - public String toString( final ConstantPool cp ) { - final Constant c = cp.getConstant(super.getIndex()); - final StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); - - final String opcodeName = Const.getOpcodeName(super.getOpcode()); - - final StringBuilder sb = new StringBuilder(opcodeName); - if (tok.hasMoreTokens()) { - sb.append(" "); - sb.append(tok.nextToken().replace('.', '/')); - if (tok.hasMoreTokens()) { - sb.append(tok.nextToken()); - } - } - - return sb.toString(); - } - - - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. + * Also works for instructions whose stack effect depends on the constant pool entry they reference. + * * @return Number of words consumed from stack by this instruction */ @Override - public int consumeStack( final ConstantPoolGen cpg ) { + public int consumeStack(final ConstantPoolGen cpg) { int sum; - if ((super.getOpcode() == Const.INVOKESTATIC) || (super.getOpcode() == Const.INVOKEDYNAMIC)) { + if (super.getOpcode() == Const.INVOKESTATIC || super.getOpcode() == Const.INVOKEDYNAMIC) { sum = 0; } else { sum = 1; // this reference @@ -93,23 +67,15 @@ return sum; } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words produced onto stack by this instruction + * @return argument types of referenced method. */ - @Override - public int produceStack( final ConstantPoolGen cpg ) { - final String signature = getSignature(cpg); - return Type.getReturnTypeSize(signature); + public Type[] getArgumentTypes(final ConstantPoolGen cpg) { + return Type.getArgumentTypes(getSignature(cpg)); } /** - * This overrides the deprecated version as we know here that the referenced class - * may legally be an array. - * - * @deprecated in FieldOrMethod + * This overrides the deprecated version as we know here that the referenced class may legally be an array. * * @return name of the referenced class/interface * @throws IllegalArgumentException if the referenced class is an array (this should not happen) @@ -120,35 +86,62 @@ final ConstantPool cp = cpg.getConstantPool(); final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); final String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class); - return className.replace('/', '.'); + return Utility.pathToPackage(className); } - /** @return return type of referenced method. + /** + * @return name of referenced method. */ - @Override - public Type getType( final ConstantPoolGen cpg ) { - return getReturnType(cpg); + public String getMethodName(final ConstantPoolGen cpg) { + return getName(cpg); } - - /** @return name of referenced method. + /** + * @return return type of referenced method. */ - public String getMethodName( final ConstantPoolGen cpg ) { - return getName(cpg); + public Type getReturnType(final ConstantPoolGen cpg) { + return Type.getReturnType(getSignature(cpg)); } - - /** @return return type of referenced method. + /** + * @return return type of referenced method. */ - public Type getReturnType( final ConstantPoolGen cpg ) { - return Type.getReturnType(getSignature(cpg)); + @Override + public Type getType(final ConstantPoolGen cpg) { + return getReturnType(cpg); } + /** + * Also works for instructions whose stack effect depends on the constant pool entry they reference. + * + * @return Number of words produced onto stack by this instruction + */ + @Override + public int produceStack(final ConstantPoolGen cpg) { + final String signature = getSignature(cpg); + return Type.getReturnTypeSize(signature); + } - /** @return argument types of referenced method. + /** + * @return mnemonic for instruction with symbolic references resolved */ - public Type[] getArgumentTypes( final ConstantPoolGen cpg ) { - return Type.getArgumentTypes(getSignature(cpg)); + @Override + public String toString(final ConstantPool cp) { + final Constant c = cp.getConstant(super.getIndex()); + final StringTokenizer tok = new StringTokenizer(cp.constantToString(c)); + + final String opcodeName = Const.getOpcodeName(super.getOpcode()); + + final StringBuilder sb = new StringBuilder(opcodeName); + if (tok.hasMoreTokens()) { + sb.append(" "); + sb.append(Utility.packageToPath(tok.nextToken())); + if (tok.hasMoreTokens()) { + sb.append(tok.nextToken()); + } + } + + return sb.toString(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEINTERFACE.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,25 +31,24 @@ /** * INVOKEINTERFACE - Invoke interface method - *
    Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    * - * @see - * - * The invokeinterface instruction in The Java Virtual Machine Specification + *
    + * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    + * 
    + * + * @see The + * invokeinterface instruction in The Java Virtual Machine Specification */ public final class INVOKEINTERFACE extends InvokeInstruction { private int nargs; // Number of arguments on stack (number of stack slots), called "count" in vmspec2 - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ INVOKEINTERFACE() { } - public INVOKEINTERFACE(final int index, final int nargs) { super(Const.INVOKEINTERFACE, index); super.setLength(5); @@ -59,84 +58,72 @@ this.nargs = nargs; } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitStackConsumer(this); + v.visitStackProducer(this); + v.visitLoadClass(this); + v.visitCPInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); + v.visitINVOKEINTERFACE(this); + } + + @Override + public int consumeStack(final ConstantPoolGen cpg) { // nargs is given in byte-code + return nargs; // nargs includes this reference + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { out.writeByte(super.getOpcode()); out.writeShort(super.getIndex()); out.writeByte(nargs); out.writeByte(0); } - /** - * The count argument according to the Java Language Specification, - * Second Edition. + * The count argument according to the Java Language Specification, Second Edition. */ public int getCount() { return nargs; } + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.ABSTRACT_METHOD_ERROR, ExceptionConst.ILLEGAL_ACCESS_ERROR, ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } /** * Read needed data (i.e., index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { super.initFromFile(bytes, wide); super.setLength(5); nargs = bytes.readUnsignedByte(); bytes.readByte(); // Skip 0 byte } - /** * @return mnemonic for instruction with symbolic references resolved */ @Override - public String toString( final ConstantPool cp ) { + public String toString(final ConstantPool cp) { return super.toString(cp) + " " + nargs; } - - - @Override - public int consumeStack( final ConstantPoolGen cpg ) { // nargs is given in byte-code - return nargs; // nargs includes this reference - } - - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_INTERFACE_METHOD_RESOLUTION, - ExceptionConst.UNSATISFIED_LINK_ERROR, - ExceptionConst.ABSTRACT_METHOD_ERROR, - ExceptionConst.ILLEGAL_ACCESS_ERROR, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitStackConsumer(this); - v.visitStackProducer(this); - v.visitLoadClass(this); - v.visitCPInstruction(this); - v.visitFieldOrMethod(this); - v.visitInvokeInstruction(this); - v.visitINVOKEINTERFACE(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESPECIAL.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,60 +28,36 @@ import com.sun.org.apache.bcel.internal.ExceptionConst; /** - * INVOKESPECIAL - Invoke instance method; special handling for superclass, private - * and instance initialization method invocations + * INVOKESPECIAL - Invoke instance method; special handling for superclass, private and instance initialization method + * invocations * - *
    Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    + *
    + * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    + * 
    * - * @see - * - * The invokespecial instruction in The Java Virtual Machine Specification + * @see The + * invokespecial instruction in The Java Virtual Machine Specification */ public class INVOKESPECIAL extends InvokeInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ INVOKESPECIAL() { } - public INVOKESPECIAL(final int index) { super(Const.INVOKESPECIAL, index); } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - out.writeShort(super.getIndex()); - } - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.NULL_POINTER_EXCEPTION, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, - ExceptionConst.ABSTRACT_METHOD_ERROR, - ExceptionConst.UNSATISFIED_LINK_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); @@ -92,4 +68,21 @@ v.visitInvokeInstruction(this); v.visitINVOKESPECIAL(this); } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, ExceptionConst.ABSTRACT_METHOD_ERROR, ExceptionConst.UNSATISFIED_LINK_ERROR); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKESTATIC.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,55 +30,33 @@ /** * INVOKESTATIC - Invoke a class (static) method * - *
    Stack: ..., [arg1, [arg2 ...]] -> ...
    + *
    + * Stack: ..., [arg1, [arg2 ...]] -> ...
    + * 
    * - * @see - * - * The invokestatic instruction in The Java Virtual Machine Specification + * @see The invokestatic + * instruction in The Java Virtual Machine Specification */ public class INVOKESTATIC extends InvokeInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ INVOKESTATIC() { } - public INVOKESTATIC(final int index) { super(Const.INVOKESTATIC, index); } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - out.writeShort(super.getIndex()); - } - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.UNSATISFIED_LINK_ERROR, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); @@ -89,4 +67,21 @@ v.visitInvokeInstruction(this); v.visitINVOKESTATIC(this); } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.UNSATISFIED_LINK_ERROR, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/INVOKEVIRTUAL.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,57 +30,33 @@ /** * INVOKEVIRTUAL - Invoke instance method; dispatch based on class * - *
    Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    + *
    + * Stack: ..., objectref, [arg1, [arg2 ...]] -> ...
    + * 
    * - * @see - * - * The invokevirtual instruction in The Java Virtual Machine Specification + * @see The + * invokevirtual instruction in The Java Virtual Machine Specification */ public class INVOKEVIRTUAL extends InvokeInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ INVOKEVIRTUAL() { } - public INVOKEVIRTUAL(final int index) { super(Const.INVOKEVIRTUAL, index); } - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - out.writeShort(super.getIndex()); - } - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.NULL_POINTER_EXCEPTION, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, - ExceptionConst.ABSTRACT_METHOD_ERROR, - ExceptionConst.UNSATISFIED_LINK_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); @@ -91,4 +67,21 @@ v.visitInvokeInstruction(this); v.visitINVOKEVIRTUAL(this); } + + /** + * Dump instruction as byte code to stream out. + * + * @param out Output stream + */ + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR, ExceptionConst.ABSTRACT_METHOD_ERROR, ExceptionConst.UNSATISFIED_LINK_ERROR); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IOR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * IOR - Bitwise OR int - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class IOR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.IOR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IREM.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,39 +24,29 @@ /** * IREM - Remainder of int - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    * @LastModified: Jan 2020 */ public class IREM extends ArithmeticInstruction implements ExceptionThrower { - /** Remainder of ints + /** + * Remainder of ints */ public IREM() { super(com.sun.org.apache.bcel.internal.Const.IREM); } - - /** @return exceptions this instruction may cause - */ - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.ARITHMETIC_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackProducer(this); @@ -64,4 +54,12 @@ v.visitArithmeticInstruction(this); v.visitIREM(this); } + + /** + * @return exceptions this instruction may cause + */ + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.ARITHMETIC_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IRETURN.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * IRETURN - Return int from method - *
    Stack: ..., value -> <empty>
    + * IRETURN - Return int from method * + *
    + * Stack: ..., value -> <empty>
    + * 
    */ public class IRETURN extends ReturnInstruction { - /** Return int from method + /** + * Return int from method */ public IRETURN() { super(com.sun.org.apache.bcel.internal.Const.IRETURN); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * ISHL - Arithmetic shift left int - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class ISHL extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.ISHL); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISHR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * ISHR - Arithmetic shift right int - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class ISHR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.ISHR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,38 +23,37 @@ /** * ISTORE - Store int from stack into local variable - *
    Stack: ..., value -> ... 
    * + *
    + * Stack: ..., value -> ...
    + * 
    */ public class ISTORE extends StoreInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ISTORE() { super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0); } - - /** Store int into local variable + /** + * Store int into local variable + * * @param n index of local variable */ public ISTORE(final int n) { super(com.sun.org.apache.bcel.internal.Const.ISTORE, com.sun.org.apache.bcel.internal.Const.ISTORE_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitISTORE(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ISUB.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * ISUB - Substract ints - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    */ public class ISUB extends ArithmeticInstruction { - /** Substract ints + /** + * Substract ints */ public ISUB() { super(com.sun.org.apache.bcel.internal.Const.ISUB); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IUSHR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * IUSHR - Logical shift right int - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class IUSHR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.IUSHR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/IXOR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * IXOR - Bitwise XOR int - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class IXOR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.IXOR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JsrInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,42 +23,33 @@ /** * Super class for JSR - Jump to subroutine - * */ -public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch, - TypedInstruction, StackProducer { - - JsrInstruction(final short opcode, final InstructionHandle target) { - super(opcode, target); - } - +public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch, TypedInstruction, StackProducer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ JsrInstruction() { } + JsrInstruction(final short opcode, final InstructionHandle target) { + super(opcode, target); + } - /** @return return address type + /** + * @return return address type */ @Override - public Type getType( final ConstantPoolGen cp ) { + public Type getType(final ConstantPoolGen cp) { return new ReturnaddressType(physicalSuccessor()); } - /** - * Returns an InstructionHandle to the physical successor - * of this JsrInstruction. For this method to work, - * this JsrInstruction object must not be shared between - * multiple InstructionHandle objects! - * Formally, there must not be InstructionHandle objects - * i, j where i != j and i.getInstruction() == this == - * j.getInstruction(). - * @return an InstructionHandle to the "next" instruction that - * will be executed when RETurned from a subroutine. + * Returns an InstructionHandle to the physical successor of this JsrInstruction. For this method to work, this + * JsrInstruction object must not be shared between multiple InstructionHandle objects! Formally, there must not be + * InstructionHandle objects i, j where i != j and i.getInstruction() == this == j.getInstruction(). + * + * @return an InstructionHandle to the "next" instruction that will be executed when RETurned from a subroutine. */ public InstructionHandle physicalSuccessor() { InstructionHandle ih = super.getTarget(); @@ -73,7 +64,7 @@ final InstructionHandle toThis = ih; while (ih != null) { ih = ih.getNext(); - if ((ih != null) && (ih.getInstruction() == this)) { + if (ih != null && ih.getInstruction() == this) { throw new IllegalStateException("physicalSuccessor() called on a shared JsrInstruction."); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,29 +26,41 @@ /** * JSR - Jump to subroutine - * */ public class JSR extends JsrInstruction implements VariableLengthInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ JSR() { } - public JSR(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.JSR, target); } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackProducer(this); + v.visitVariableLengthInstruction(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { super.setIndex(getTargetOffset()); if (super.getOpcode() == com.sun.org.apache.bcel.internal.Const.JSR) { super.dump(out); @@ -59,35 +71,16 @@ } } - @Override - protected int updatePosition( final int offset, final int max_offset ) { + protected int updatePosition(final int offset, final int maxOffset) { final int i = getTargetOffset(); // Depending on old position value setPosition(getPosition() + offset); // Position may be shifted by preceding expansions - if (Math.abs(i) >= (Short.MAX_VALUE - max_offset)) { // to large for short (estimate) + if (Math.abs(i) >= Short.MAX_VALUE - maxOffset) { // to large for short (estimate) super.setOpcode(com.sun.org.apache.bcel.internal.Const.JSR_W); - final short old_length = (short) super.getLength(); + final short oldLength = (short) super.getLength(); super.setLength(5); - return super.getLength() - old_length; + return super.getLength() - oldLength; } return 0; } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitStackProducer(this); - v.visitVariableLengthInstruction(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/JSR_W.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,59 +28,52 @@ /** * JSR_W - Jump to subroutine - * */ public class JSR_W extends JsrInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ JSR_W() { } - public JSR_W(final InstructionHandle target) { super(com.sun.org.apache.bcel.internal.Const.JSR_W, target); super.setLength(5); } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackProducer(this); + v.visitBranchInstruction(this); + v.visitJsrInstruction(this); + v.visitJSR_W(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { super.setIndex(getTargetOffset()); out.writeByte(super.getOpcode()); out.writeInt(super.getIndex()); } - /** * Read needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { super.setIndex(bytes.readInt()); super.setLength(5); } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitStackProducer(this); - v.visitBranchInstruction(this); - v.visitJsrInstruction(this); - v.visitJSR_W(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2D.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * L2D - Convert long to double - *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    + * 
    */ public class L2D extends ConversionInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.L2D); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2F.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * L2F - Convert long to float - *
    Stack: ..., value.word1, value.word2 -> ..., result
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result
    + * 
    */ public class L2F extends ConversionInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.L2F); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/L2I.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * L2I - Convert long to int - *
    Stack: ..., value.word1, value.word2 -> ..., result
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result
    + * 
    */ public class L2I extends ConversionInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.L2I); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LADD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,9 +23,12 @@ /** * LADD - Add longs - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class LADD extends ArithmeticInstruction { @@ -33,17 +36,14 @@ super(com.sun.org.apache.bcel.internal.Const.LADD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,28 +23,28 @@ /** * LALOAD - Load long from array - *
    Stack: ..., arrayref, index -> ..., value1, value2
    * + *
    + * Stack: ..., arrayref, index -> ..., value1, value2
    + * 
    */ public class LALOAD extends ArrayInstruction implements StackProducer { - /** Load long from array + /** + * Load long from array */ public LALOAD() { super(com.sun.org.apache.bcel.internal.Const.LALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LAND.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,9 +23,12 @@ /** * LAND - Bitwise AND longs - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class LAND extends ArithmeticInstruction { @@ -33,17 +36,14 @@ super(com.sun.org.apache.bcel.internal.Const.LAND); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,29 +22,29 @@ package com.sun.org.apache.bcel.internal.generic; /** - * LASTORE - Store into long array - *
    Stack: ..., arrayref, index, value.word1, value.word2 -> ...
    + * LASTORE - Store into long array * + *
    + * Stack: ..., arrayref, index, value.word1, value.word2 -> ...
    + * 
    */ public class LASTORE extends ArrayInstruction implements StackConsumer { - /** Store long into array + /** + * Store long into array */ public LASTORE() { super(com.sun.org.apache.bcel.internal.Const.LASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCMP.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LCMP - Compare longs: - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result <= -1, 0, 1>
    * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -> ..., result <= -1, 0, 1>
    + * 
    * */ public class LCMP extends Instruction implements TypedInstruction, StackProducer, StackConsumer { @@ -33,28 +35,25 @@ super(com.sun.org.apache.bcel.internal.Const.LCMP, (short) 1); } - - /** @return Type.LONG - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.LONG; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); v.visitLCMP(this); } + + /** + * @return Type.LONG + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.LONG; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LCONST.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,22 +23,21 @@ /** * LCONST - Push 0 or 1, other values cause an exception * - *
    Stack: ... -> ..., 
    - * + *
    + * Stack: ... -> ...,
    + * 
    */ public class LCONST extends Instruction implements ConstantPushInstruction { - private long value; - + private final long value; /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LCONST() { + this(0); } - public LCONST(final long l) { super(com.sun.org.apache.bcel.internal.Const.LCONST_0, (short) 1); if (l == 0) { @@ -51,35 +50,31 @@ value = l; } - - @Override - public Number getValue() { - return Long.valueOf(value); - } - - - /** @return Type.LONG - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.LONG; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitPushInstruction(this); v.visitStackProducer(this); v.visitTypedInstruction(this); v.visitConstantPushInstruction(this); v.visitLCONST(this); } + + /** + * @return Type.LONG + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return Type.LONG; + } + + @Override + public Number getValue() { + return Long.valueOf(value); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC2_W.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,65 +23,59 @@ /** * LDC2_W - Push long or double from constant pool * - *
    Stack: ... -> ..., item.word1, item.word2
    - * + *
    + * Stack: ... -> ..., item.word1, item.word2
    + * 
    * @LastModified: May 2021 */ public class LDC2_W extends CPInstruction implements PushInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LDC2_W() { } - public LDC2_W(final int index) { super(com.sun.org.apache.bcel.internal.Const.LDC2_W, index); } - - @Override - public Type getType( final ConstantPoolGen cpg ) { - switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: - return Type.LONG; - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: - return Type.DOUBLE; - default: // Never reached - throw new IllegalArgumentException("Unknown constant type " + super.getOpcode()); - } - } - - - public Number getValue( final ConstantPoolGen cpg ) { - final com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); - switch (c.getTag()) { - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: - return ((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes(); - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: - return ((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes(); - default: // Never reached - throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); - } - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitPushInstruction(this); v.visitTypedInstruction(this); v.visitCPInstruction(this); v.visitLDC2_W(this); } + + @Override + public Type getType(final ConstantPoolGen cpg) { + switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: + return Type.LONG; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: + return Type.DOUBLE; + default: // Never reached + throw new IllegalArgumentException("Unknown constant type " + super.getOpcode()); + } + } + + public Number getValue(final ConstantPoolGen cpg) { + final com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); + switch (c.getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Long: + return Long.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantLong) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Double: + return Double.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantDouble) c).getBytes()); + default: // Never reached + throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,44 +29,47 @@ /** * LDC - Push item from constant pool. * - *
    Stack: ... -> ..., item
    - * + *
    + * Stack: ... -> ..., item
    + * 
    * @LastModified: May 2021 */ public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LDC() { } - public LDC(final int index) { super(com.sun.org.apache.bcel.internal.Const.LDC_W, index); setSize(); } - - // Adjust to proper size - protected final void setSize() { - if (super.getIndex() <= com.sun.org.apache.bcel.internal.Const.MAX_BYTE) { // Fits in one byte? - super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC); - super.setLength(2); - } else { - super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); - super.setLength(3); - } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitStackProducer(this); + v.visitPushInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitLDC(this); } - /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { out.writeByte(super.getOpcode()); if (super.getLength() == 2) { // TODO useless check? out.writeByte(super.getIndex()); @@ -75,86 +78,73 @@ } } - - /** - * Set the index to constant pool and adjust size. - */ @Override - public final void setIndex( final int index ) { - super.setIndex(index); - setSize(); + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_STRING_RESOLUTION); } - - /** - * Read needed data (e.g. index) from file. - */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - super.setLength(2); - super.setIndex(bytes.readUnsignedByte()); + public Type getType(final ConstantPoolGen cpg) { + switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { + case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: + return Type.STRING; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: + return Type.FLOAT; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: + return Type.INT; + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: + return Type.CLASS; + default: // Never reached + throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); + } } - - public Object getValue( final ConstantPoolGen cpg ) { + public Object getValue(final ConstantPoolGen cpg) { com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(super.getIndex()); switch (c.getTag()) { - case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: - final int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString) c).getStringIndex(); - c = cpg.getConstantPool().getConstant(i); - return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes(); - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: - return ((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes(); - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: - return ((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes(); - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: - final int nameIndex = ((com.sun.org.apache.bcel.internal.classfile.ConstantClass) c).getNameIndex(); - c = cpg.getConstantPool().getConstant(nameIndex); - return new ObjectType(((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes()); - default: // Never reached - throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); - } - } - - - @Override - public Type getType( final ConstantPoolGen cpg ) { - switch (cpg.getConstantPool().getConstant(super.getIndex()).getTag()) { - case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: - return Type.STRING; - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: - return Type.FLOAT; - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: - return Type.INT; - case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: - return Type.CLASS; - default: // Never reached - throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_String: + final int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString) c).getStringIndex(); + c = cpg.getConstantPool().getConstant(i); + return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes(); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Float: + return Float.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Integer: + return Integer.valueOf(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger) c).getBytes()); + case com.sun.org.apache.bcel.internal.Const.CONSTANT_Class: + final int nameIndex = ((com.sun.org.apache.bcel.internal.classfile.ConstantClass) c).getNameIndex(); + c = cpg.getConstantPool().getConstant(nameIndex); + return Type.getType(((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8) c).getBytes()); + default: // Never reached + throw new IllegalArgumentException("Unknown or invalid constant type at " + super.getIndex()); } } - + /** + * Read needed data (e.g. index) from file. + */ @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_STRING_RESOLUTION); + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(2); + super.setIndex(bytes.readUnsignedByte()); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object + * Set the index to constant pool and adjust size. */ @Override - public void accept( final Visitor v ) { - v.visitStackProducer(this); - v.visitPushInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitLDC(this); + public final void setIndex(final int index) { + super.setIndex(index); + setSize(); + } + + // Adjust to proper size + protected final void setSize() { + if (super.getIndex() <= com.sun.org.apache.bcel.internal.Const.MAX_BYTE) { // Fits in one byte? + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC); + super.setLength(2); + } else { + super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); + super.setLength(3); + } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDC_W.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,29 +28,27 @@ /** * LDC_W - Push item from constant pool (wide index) * - *
    Stack: ... -> ..., item.word1, item.word2
    - * + *
    + * Stack: ... -> ..., item.word1, item.word2
    + * 
    */ public class LDC_W extends LDC { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LDC_W() { } - public LDC_W(final int index) { super(index); } - /** * Read needed data (i.e., index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { setIndex(bytes.readUnsignedShort()); // Override just in case it has been changed super.setOpcode(com.sun.org.apache.bcel.internal.Const.LDC_W); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LDIV.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,9 +24,12 @@ /** * LDIV - Divide longs - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 * @LastModified: Jan 2020 */ public class LDIV extends ArithmeticInstruction implements ExceptionThrower { @@ -35,25 +38,14 @@ super(com.sun.org.apache.bcel.internal.Const.LDIV); } - - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.ARITHMETIC_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackProducer(this); @@ -61,4 +53,9 @@ v.visitArithmeticInstruction(this); v.visitLDIV(this); } + + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.ARITHMETIC_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,14 +26,16 @@ import com.sun.org.apache.bcel.internal.classfile.LineNumber; /** - * This class represents a line number within a method, i.e., give an instruction - * a line number corresponding to the source code line. + * This class represents a line number within a method, i.e., give an instruction a line number corresponding to the + * source code line. * - * @see LineNumber - * @see MethodGen + * @see LineNumber + * @see MethodGen */ public class LineNumberGen implements InstructionTargeter, Cloneable { + static final LineNumberGen[] EMPTY_ARRAY = {}; + private InstructionHandle ih; private int srcLine; @@ -42,73 +44,65 @@ * * @param ih instruction handle to reference */ - public LineNumberGen(final InstructionHandle ih, final int src_line) { + public LineNumberGen(final InstructionHandle ih, final int srcLine) { setInstruction(ih); - setSourceLine(src_line); + setSourceLine(srcLine); } + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } /** * @return true, if ih is target of this line number */ @Override - public boolean containsTarget( final InstructionHandle ih ) { + public boolean containsTarget(final InstructionHandle ih) { return this.ih == ih; } - - /** - * @param old_ih old target - * @param new_ih new target - */ - @Override - public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { - if (old_ih != ih) { - throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); - } - setInstruction(new_ih); + public InstructionHandle getInstruction() { + return ih; } - /** - * Get LineNumber attribute . + * Get LineNumber attribute. * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. + * This relies on that the instruction list has already been dumped to byte code or that the 'setPositions' methods + * has been called for the instruction list. */ public LineNumber getLineNumber() { return new LineNumber(ih.getPosition(), srcLine); } + public int getSourceLine() { + return srcLine; + } - public void setInstruction( final InstructionHandle instructionHandle ) { // TODO could be package-protected? + public void setInstruction(final InstructionHandle instructionHandle) { // TODO could be package-protected? Objects.requireNonNull(instructionHandle, "instructionHandle"); BranchInstruction.notifyTarget(this.ih, instructionHandle, this); this.ih = instructionHandle; } + public void setSourceLine(final int srcLine) { // TODO could be package-protected? + this.srcLine = srcLine; + } + /** + * @param oldIh old target + * @param newIh new target + */ @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - throw new Error("Clone Not Supported"); // never happens + public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) { + if (oldIh != ih) { + throw new ClassGenException("Not targeting " + oldIh + ", but " + ih + "}"); } - } - - - public InstructionHandle getInstruction() { - return ih; - } - - - public void setSourceLine( final int src_line ) { // TODO could be package-protected? - this.srcLine = src_line; - } - - - public int getSourceLine() { - return srcLine; + setInstruction(newIh); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LLOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,35 +23,32 @@ /** * LLOAD - Load long from local variable - *
    Stack ... -> ..., result.word1, result.word2
    * + *
    + * Stack ... -> ..., result.word1, result.word2
    + * 
    */ public class LLOAD extends LoadInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LLOAD() { super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0); } - public LLOAD(final int n) { super(com.sun.org.apache.bcel.internal.Const.LLOAD, com.sun.org.apache.bcel.internal.Const.LLOAD_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitLLOAD(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LMUL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,9 +23,12 @@ /** * LMUL - Multiply longs - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class LMUL extends ArithmeticInstruction { @@ -33,17 +36,14 @@ super(com.sun.org.apache.bcel.internal.Const.LMUL); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LNEG.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LNEG - Negate long - *
    Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2
    + * 
    */ public class LNEG extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LNEG); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,32 +22,27 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denotes that an instruction may start the process of loading and resolving - * the referenced class in the Virtual Machine. - * + * Denotes that an instruction may start the process of loading and resolving the referenced class in the Virtual Machine. */ public interface LoadClass { /** - * Returns the ObjectType of the referenced class or interface - * that may be loaded and resolved. - * @return object type that may be loaded or null if a primitive is - * referenced + * Returns the {@link ObjectType} of the referenced class or interface that may be loaded and resolved. + * + * @param cpg A ConstantPoolGen + * @return object type that may be loaded or null if a primitive is referenced */ - ObjectType getLoadClassType( ConstantPoolGen cpg ); - + ObjectType getLoadClassType(ConstantPoolGen cpg); /** - * Returns the type associated with this instruction. - * LoadClass instances are always typed, but this type - * does not always refer to the type of the class or interface - * that it possibly forces to load. For example, GETFIELD would - * return the type of the field and not the type of the class - * where the field is defined. - * If no class is forced to be loaded, null is returned. - * An example for this is an ANEWARRAY instruction that creates - * an int[][]. + * Returns the type associated with this instruction. LoadClass instances are always typed, but this type does not always refer to the type of the class or + * interface that it possibly forces to load. For example, {@link GETFIELD} would return the type of the field and not the type of the class where the field + * is defined. If no class is forced to be loaded, {@code null} is returned. An example for this is an {@link NEWARRAY} instruction that creates an + * {@code int[][]}. + * + * @param cpg A ConstantPoolGen + * @return the type associated with this instruction. * @see #getLoadClassType(ConstantPoolGen) */ - Type getType( ConstantPoolGen cpg ); + Type getType(ConstantPoolGen cpg); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LoadInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,42 +22,35 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denotes an unparameterized instruction to load a value from a local - * variable, e.g. ILOAD. - * + * Denotes an unparameterized instruction to load a value from a local variable, e.g. ILOAD. */ public abstract class LoadInstruction extends LocalVariableInstruction implements PushInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. tag and length are defined in + * readInstruction and initFromFile, respectively. */ - LoadInstruction(final short canon_tag, final short c_tag) { - super(canon_tag, c_tag); + LoadInstruction(final short canonTag, final short cTag) { + super(canonTag, cTag); } - /** * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ALOAD_0, e.g. + * @param cTag Instruction number for compact version, ALOAD_0, e.g. * @param n local variable index (unsigned short) */ - protected LoadInstruction(final short opcode, final short c_tag, final int n) { - super(opcode, c_tag, n); + protected LoadInstruction(final short opcode, final short cTag, final int n) { + super(opcode, cTag, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitPushInstruction(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,13 +24,11 @@ import com.sun.org.apache.bcel.internal.classfile.LocalVariable; /** - * Represents a local variable within a method. It contains its - * scope, name and type. The generated LocalVariable object can be obtained - * with getLocalVariable which needs the instruction list and the constant - * pool as parameters. + * Represents a local variable within a method. It contains its scope, name and type. The generated LocalVariable object + * can be obtained with getLocalVariable which needs the instruction list and the constant pool as parameters. * - * @see LocalVariable - * @see MethodGen + * @see LocalVariable + * @see MethodGen */ public class LocalVariableGen implements InstructionTargeter, NamedAndTyped, Cloneable { @@ -42,10 +40,9 @@ private int origIndex; // never changes; used to match up with LocalVariableTypeTable entries private boolean liveToEnd; - /** - * Generate a local variable that with index `index'. Note that double and long - * variables need two indexs. Index indices have to be provided by the user. + * Generate a local variable that with index 'index'. Note that double and long variables need two indexs. Index indices + * have to be provided by the user. * * @param index index of local variable * @param name its name @@ -53,10 +50,9 @@ * @param start from where the instruction is valid (null means from the start) * @param end until where the instruction is valid (null means to the end) */ - public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, - final InstructionHandle end) { - if ((index < 0) || (index > Const.MAX_SHORT)) { - throw new ClassGenException("Invalid index index: " + index); + public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, final InstructionHandle end) { + if (index < 0 || index > Const.MAX_SHORT) { + throw new ClassGenException("Invalid index: " + index); } this.name = name; this.type = type; @@ -67,10 +63,9 @@ this.liveToEnd = end == null; } - /** - * Generates a local variable that with index `index'. Note that double and long - * variables need two indexs. Index indices have to be provided by the user. + * Generates a local variable that with index 'index'. Note that double and long variables need two indexs. Index + * indices have to be provided by the user. * * @param index index of local variable * @param name its name @@ -79,187 +74,163 @@ * @param end until where the instruction is valid (null means to the end) * @param origIndex index of local variable prior to any changes to index */ - public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, - final InstructionHandle end, final int origIndex) { + public LocalVariableGen(final int index, final String name, final Type type, final InstructionHandle start, final InstructionHandle end, + final int origIndex) { this(index, name, type, start, end); this.origIndex = origIndex; } + @Override + public Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + throw new Error("Clone Not Supported"); // never happens + } + } /** - * Gets LocalVariable object. - * - * This relies on that the instruction list has already been dumped to byte code or - * or that the `setPositions' methods has been called for the instruction list. - * - * Note that due to the conversion from byte code offset to InstructionHandle, - * it is impossible to tell the difference between a live range that ends BEFORE - * the last insturction of the method or a live range that ends AFTER the last - * instruction of the method. Hence the liveToEnd flag to differentiate - * between these two cases. - * - * @param cp constant pool + * @return true, if ih is target of this variable */ - public LocalVariable getLocalVariable( final ConstantPoolGen cp ) { - int start_pc = 0; - int length = 0; - if ((start != null) && (end != null)) { - start_pc = start.getPosition(); - length = end.getPosition() - start_pc; - if ((end.getNext() == null) && liveToEnd) { - length += end.getInstruction().getLength(); - } - } - final int name_index = cp.addUtf8(name); - final int signature_index = cp.addUtf8(type.getSignature()); - return new LocalVariable(start_pc, length, name_index, signature_index, index, cp - .getConstantPool(), origIndex); + @Override + public boolean containsTarget(final InstructionHandle ih) { + return start == ih || end == ih; } - - public void setIndex( final int index ) { - this.index = index; + /** + * Clear the references from and to this variable when it's removed. + */ + void dispose() { + setStart(null); + setEnd(null); } - - public int getIndex() { - return index; + /** + * We consider to local variables to be equal, if the use the same index and are valid in the same range. + */ + @Override + public boolean equals(final Object o) { + if (!(o instanceof LocalVariableGen)) { + return false; + } + final LocalVariableGen l = (LocalVariableGen) o; + return l.index == index && l.start == start && l.end == end; } - - public int getOrigIndex() { - return origIndex; + public InstructionHandle getEnd() { + return end; } - - public void setLiveToEnd( final boolean live_to_end) { - this.liveToEnd = live_to_end; + public int getIndex() { + return index; } - public boolean getLiveToEnd() { return liveToEnd; } - - @Override - public void setName( final String name ) { - this.name = name; + /** + * Gets LocalVariable object. + * + * This relies on that the instruction list has already been dumped to byte code or that the 'setPositions' methods + * has been called for the instruction list. + * + * Note that due to the conversion from byte code offset to InstructionHandle, it is impossible to tell the difference + * between a live range that ends BEFORE the last insturction of the method or a live range that ends AFTER the last + * instruction of the method. Hence the liveToEnd flag to differentiate between these two cases. + * + * @param cp constant pool + */ + public LocalVariable getLocalVariable(final ConstantPoolGen cp) { + int startPc = 0; + int length = 0; + if (start != null && end != null) { + startPc = start.getPosition(); + length = end.getPosition() - startPc; + if (end.getNext() == null && liveToEnd) { + length += end.getInstruction().getLength(); + } + } + final int nameIndex = cp.addUtf8(name); + final int signatureIndex = cp.addUtf8(type.getSignature()); + return new LocalVariable(startPc, length, nameIndex, signatureIndex, index, cp.getConstantPool(), origIndex); } - @Override public String getName() { return name; } - - @Override - public void setType( final Type type ) { - this.type = type; - } - - - @Override - public Type getType() { - return type; + public int getOrigIndex() { + return origIndex; } - public InstructionHandle getStart() { return start; } - - public InstructionHandle getEnd() { - return end; + @Override + public Type getType() { + return type; } - - public void setStart( final InstructionHandle start ) { // TODO could be package-protected? - BranchInstruction.notifyTarget(this.start, start, this); - this.start = start; + @Override + public int hashCode() { + // If the user changes the name or type, problems with the targeter hashmap will occur. + // Note: index cannot be part of hash as it may be changed by the user. + return name.hashCode() ^ type.hashCode(); } - - public void setEnd( final InstructionHandle end ) { // TODO could be package-protected? + public void setEnd(final InstructionHandle end) { // TODO could be package-protected? BranchInstruction.notifyTarget(this.end, end, this); this.end = end; } - - /** - * @param old_ih old target, either start or end - * @param new_ih new target - */ - @Override - public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { - boolean targeted = false; - if (start == old_ih) { - targeted = true; - setStart(new_ih); - } - if (end == old_ih) { - targeted = true; - setEnd(new_ih); - } - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih + ", but {" + start + ", " + end - + "}"); - } + public void setIndex(final int index) { + this.index = index; } - /** - * Clear the references from and to this variable when it's removed. - */ - void dispose() { - setStart(null); - setEnd(null); + public void setLiveToEnd(final boolean liveToEnd) { + this.liveToEnd = liveToEnd; } - /** - * @return true, if ih is target of this variable - */ @Override - public boolean containsTarget( final InstructionHandle ih ) { - return (start == ih) || (end == ih); + public void setName(final String name) { + this.name = name; } - - @Override - public int hashCode() { - // If the user changes the name or type, problems with the targeter hashmap will occur. - // Note: index cannot be part of hash as it may be changed by the user. - return name.hashCode() ^ type.hashCode(); + public void setStart(final InstructionHandle start) { // TODO could be package-protected? + BranchInstruction.notifyTarget(this.start, start, this); + this.start = start; } - - /** - * We consider to local variables to be equal, if the use the same index and - * are valid in the same range. - */ @Override - public boolean equals( final Object o ) { - if (!(o instanceof LocalVariableGen)) { - return false; - } - final LocalVariableGen l = (LocalVariableGen) o; - return (l.index == index) && (l.start == start) && (l.end == end); + public void setType(final Type type) { + this.type = type; } - @Override public String toString() { return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; } - + /** + * @param oldIh old target, either start or end + * @param newIh new target + */ @Override - public Object clone() { - try { - return super.clone(); - } catch (final CloneNotSupportedException e) { - throw new Error("Clone Not Supported"); // never happens + public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) { + boolean targeted = false; + if (start == oldIh) { + targeted = true; + setStart(newIh); + } + if (end == oldIh) { + targeted = true; + setEnd(newIh); + } + if (!targeted) { + throw new ClassGenException("Not targeting " + oldIh + ", but {" + start + ", " + end + "}"); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LocalVariableInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,39 +30,32 @@ * * @LastModified: May 2021 */ -public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction, - IndexedInstruction { +public abstract class LocalVariableInstruction extends Instruction implements TypedInstruction, IndexedInstruction { + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int n = -1; // index of referenced variable - private int n = -1; // index of referenced variable private short cTag = -1; // compact version, such as ILOAD_0 private short canonTag = -1; // canonical tag such as ILOAD - - private boolean wide() { - return n > Const.MAX_BYTE; - } - - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. + * Empty constructor needed for Instruction.readInstruction. Also used by IINC()! */ - LocalVariableInstruction(final short canon_tag, final short c_tag) { - super(); - this.canonTag = canon_tag; - this.cTag = c_tag; + LocalVariableInstruction() { } - /** - * Empty constructor needed for Instruction.readInstruction. - * Also used by IINC()! + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. tag and length are defined in + * readInstruction and initFromFile, respectively. */ - LocalVariableInstruction() { + LocalVariableInstruction(final short canonTag, final short cTag) { + this.canonTag = canonTag; + this.cTag = cTag; } - /** * @param opcode Instruction opcode * @param cTag Instruction number for compact version, ALOAD_0, e.g. @@ -75,13 +68,13 @@ setIndex(n); } - /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { if (wide()) { out.writeByte(Const.WIDE); } @@ -95,73 +88,87 @@ } } + /** + * @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 + */ + public short getCanonicalTag() { + return canonTag; + } /** - * Long output format: - * - * <name of opcode> "["<opcode number>"]" - * "("<length of instruction>")" "<"< local variable index>">" + * @return local variable index (n) referred by this instruction. + */ + @Override + public final int getIndex() { + return n; + } + + /** + * Returns the type associated with the instruction - in case of ALOAD or ASTORE Type.OBJECT is returned. This is just a + * bit incorrect, because ALOAD and ASTORE may work on every ReferenceType (including Type.NULL) and ASTORE may even + * work on a ReturnaddressType . * - * @param verbose long/short format switch - * @return mnemonic for instruction + * @return type associated with the instruction */ @Override - public String toString( final boolean verbose ) { - final short _opcode = super.getOpcode(); - if (((_opcode >= Const.ILOAD_0) && (_opcode <= Const.ALOAD_3)) - || ((_opcode >= Const.ISTORE_0) && (_opcode <= Const.ASTORE_3))) { - return super.toString(verbose); + public Type getType(final ConstantPoolGen cp) { + switch (canonTag) { + case Const.ILOAD: + case Const.ISTORE: + return Type.INT; + case Const.LLOAD: + case Const.LSTORE: + return Type.LONG; + case Const.DLOAD: + case Const.DSTORE: + return Type.DOUBLE; + case Const.FLOAD: + case Const.FSTORE: + return Type.FLOAT; + case Const.ALOAD: + case Const.ASTORE: + return Type.OBJECT; + default: + throw new ClassGenException("Unknown case in switch" + canonTag); } - return super.toString(verbose) + " " + n; } - /** * Read needed data (e.g. index) from file. + * *
          * (ILOAD <= tag <= ALOAD_3) || (ISTORE <= tag <= ASTORE_3)
          * 
    */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { if (wide) { n = bytes.readUnsignedShort(); super.setLength(4); } else { - final short _opcode = super.getOpcode(); - if (((_opcode >= Const.ILOAD) && (_opcode <= Const.ALOAD)) - || ((_opcode >= Const.ISTORE) && (_opcode <= Const.ASTORE))) { + final short opcode = super.getOpcode(); + if (opcode >= Const.ILOAD && opcode <= Const.ALOAD || opcode >= Const.ISTORE && opcode <= Const.ASTORE) { n = bytes.readUnsignedByte(); super.setLength(2); - } else if (_opcode <= Const.ALOAD_3) { // compact load instruction such as ILOAD_2 - n = (_opcode - Const.ILOAD_0) % 4; - super.setLength(1); - } else { // Assert ISTORE_0 <= tag <= ASTORE_3 - n = (_opcode - Const.ISTORE_0) % 4; + } else { + if (opcode <= Const.ALOAD_3) { // compact load instruction such as ILOAD_2 + n = (opcode - Const.ILOAD_0) % 4; + } else { // Assert ISTORE_0 <= tag <= ASTORE_3 + n = (opcode - Const.ISTORE_0) % 4; + } super.setLength(1); } } } - - /** - * @return local variable index (n) referred by this instruction. - */ - @Override - public final int getIndex() { - return n; - } - - /** - * Set the local variable index. - * also updates opcode and length - * TODO Why? + * Set the local variable index. also updates opcode and length TODO Why? + * * @see #setIndexOnly(int) */ @Override - public void setIndex( final int n ) { // TODO could be package-protected? - if ((n < 0) || (n > Const.MAX_SHORT)) { + public void setIndex(final int n) { // TODO could be package-protected? + if (n < 0 || n > Const.MAX_SHORT) { throw new ClassGenException("Illegal value: " + n); } this.n = n; @@ -179,51 +186,35 @@ } } - - /** @return canonical tag for instruction, e.g., ALOAD for ALOAD_0 + /** + * Sets the index of the referenced variable (n) only + * + * @since 6.0 + * @see #setIndex(int) */ - public short getCanonicalTag() { - return canonTag; + final void setIndexOnly(final int n) { + this.n = n; } - /** - * Returns the type associated with the instruction - - * in case of ALOAD or ASTORE Type.OBJECT is returned. - * This is just a bit incorrect, because ALOAD and ASTORE - * may work on every ReferenceType (including Type.NULL) and - * ASTORE may even work on a ReturnaddressType . - * @return type associated with the instruction + * Long output format: + * + * <name of opcode> "["<opcode number>"]" "("<length of instruction>")" "<"< local variable + * index>">" + * + * @param verbose long/short format switch + * @return mnemonic for instruction */ @Override - public Type getType( final ConstantPoolGen cp ) { - switch (canonTag) { - case Const.ILOAD: - case Const.ISTORE: - return Type.INT; - case Const.LLOAD: - case Const.LSTORE: - return Type.LONG; - case Const.DLOAD: - case Const.DSTORE: - return Type.DOUBLE; - case Const.FLOAD: - case Const.FSTORE: - return Type.FLOAT; - case Const.ALOAD: - case Const.ASTORE: - return Type.OBJECT; - default: - throw new ClassGenException("Unknown case in switch" + canonTag); + public String toString(final boolean verbose) { + final short opcode = super.getOpcode(); + if (opcode >= Const.ILOAD_0 && opcode <= Const.ALOAD_3 || opcode >= Const.ISTORE_0 && opcode <= Const.ASTORE_3) { + return super.toString(verbose); } + return super.toString(verbose) + " " + n; } - /** - * Sets the index of the referenced variable (n) only - * @since 6.0 - * @see #setIndex(int) - */ - final void setIndexOnly(final int n) { - this.n = n; + private boolean wide() { + return n > Const.MAX_BYTE; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOOKUPSWITCH.java 2023-10-06 05:33:33.000000000 +0000 @@ -34,75 +34,68 @@ public class LOOKUPSWITCH extends Select { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LOOKUPSWITCH() { } - - public LOOKUPSWITCH(final int[] match, final InstructionHandle[] targets, - final InstructionHandle defaultTarget) { + public LOOKUPSWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) { super(com.sun.org.apache.bcel.internal.Const.LOOKUPSWITCH, match, targets, defaultTarget); /* alignment remainder assumed 0 here, until dump time. */ - final short _length = (short) (9 + getMatch_length() * 8); - super.setLength(_length); - setFixed_length(_length); + final short length = (short) (9 + getMatchLength() * 8); + super.setLength(length); + setFixedLength(length); } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitVariableLengthInstruction(this); + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitLOOKUPSWITCH(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { super.dump(out); - final int _match_length = getMatch_length(); - out.writeInt(_match_length); // npairs - for (int i = 0; i < _match_length; i++) { + final int matchLength = getMatchLength(); + out.writeInt(matchLength); // npairs + for (int i = 0; i < matchLength; i++) { out.writeInt(super.getMatch(i)); // match-offset pairs out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i)))); } } - /** * Read needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { super.initFromFile(bytes, wide); // reads padding - final int _match_length = bytes.readInt(); - setMatch_length(_match_length); - final short _fixed_length = (short) (9 + _match_length * 8); - setFixed_length(_fixed_length); - final short _length = (short) (_match_length + super.getPadding()); - super.setLength(_length); - super.setMatches(new int[_match_length]); - super.setIndices(new int[_match_length]); - super.setTargets(new InstructionHandle[_match_length]); - for (int i = 0; i < _match_length; i++) { + final int matchLength = bytes.readInt(); + setMatchLength(matchLength); + final short fixedLength = (short) (9 + matchLength * 8); + setFixedLength(fixedLength); + final short length = (short) (matchLength + super.getPadding()); + super.setLength(length); + super.setMatches(new int[matchLength]); + super.setIndices(new int[matchLength]); + super.setTargets(new InstructionHandle[matchLength]); + for (int i = 0; i < matchLength; i++) { super.setMatch(i, bytes.readInt()); super.setIndices(i, bytes.readInt()); } } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitVariableLengthInstruction(this); - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitLOOKUPSWITCH(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LOR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LOR - Bitwise OR long - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class LOR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LOR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LREM.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,8 +24,10 @@ /** * LREM - Remainder of long - *
    Stack: ..., value1, value2 -> result
    * + *
    + * Stack: ..., value1, value2 -> result
    + * 
    * @LastModified: Jan 2020 */ public class LREM extends ArithmeticInstruction implements ExceptionThrower { @@ -34,25 +36,14 @@ super(com.sun.org.apache.bcel.internal.Const.LREM); } - - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.ARITHMETIC_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackProducer(this); @@ -60,4 +51,9 @@ v.visitArithmeticInstruction(this); v.visitLREM(this); } + + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.ARITHMETIC_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LRETURN.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,9 +22,11 @@ package com.sun.org.apache.bcel.internal.generic; /** - * LRETURN - Return long from method - *
    Stack: ..., value.word1, value.word2 -> <empty>
    + * LRETURN - Return long from method * + *
    + * Stack: ..., value.word1, value.word2 -> <empty>
    + * 
    */ public class LRETURN extends ReturnInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LRETURN); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHL.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LSHL - Arithmetic shift left long - *
    Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
    + * 
    */ public class LSHL extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LSHL); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSHR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LSHR - Arithmetic shift right long - *
    Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
    * + *
    + * Stack: ..., value1.word1, value1.word2, value2 -> ..., result.word1, result.word2
    + * 
    */ public class LSHR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LSHR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,35 +23,32 @@ /** * LSTORE - Store long into local variable - *
    Stack: ..., value.word1, value.word2 -> ... 
    * + *
    + * Stack: ..., value.word1, value.word2 -> ...
    + * 
    */ public class LSTORE extends StoreInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ LSTORE() { super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0); } - public LSTORE(final int n) { super(com.sun.org.apache.bcel.internal.Const.LSTORE, com.sun.org.apache.bcel.internal.Const.LSTORE_0, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { super.accept(v); v.visitLSTORE(this); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LSUB.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,9 +23,12 @@ /** * LSUB - Substract longs - *
    Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    - * ..., result.word1, result.word2 * + *
    + * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
    + * 
    + * + * ..., result.word1, result.word2 */ public class LSUB extends ArithmeticInstruction { @@ -33,17 +36,14 @@ super(com.sun.org.apache.bcel.internal.Const.LSUB); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LUSHR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LUSHR - Logical shift right long - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class LUSHR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LUSHR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/LXOR.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * LXOR - Bitwise XOR long - *
    Stack: ..., value1, value2 -> ..., result
    * + *
    + * Stack: ..., value1, value2 -> ..., result
    + * 
    */ public class LXOR extends ArithmeticInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.LXOR); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitTypedInstruction(this); v.visitStackProducer(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -19,6 +19,15 @@ */ package com.sun.org.apache.bcel.internal.generic; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; +import java.util.Stack; + import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry; import com.sun.org.apache.bcel.internal.classfile.Annotations; @@ -37,96 +46,223 @@ import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations; import com.sun.org.apache.bcel.internal.classfile.Utility; import com.sun.org.apache.bcel.internal.util.BCELComparator; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Stack; /** - * Template class for building up a method. This is done by defining exception - * handlers, adding thrown exceptions, local variables and attributes, whereas - * the `LocalVariableTable' and `LineNumberTable' attributes will be set - * automatically for the code. Use stripAttributes() if you don't like this. + * Template class for building up a method. This is done by defining exception handlers, adding thrown exceptions, local + * variables and attributes, whereas the 'LocalVariableTable' and 'LineNumberTable' attributes will be set automatically + * for the code. Use stripAttributes() if you don't like this. * - * While generating code it may be necessary to insert NOP operations. You can - * use the `removeNOPs' method to get rid off them. - * The resulting method object can be obtained via the `getMethod()' method. + * While generating code it may be necessary to insert NOP operations. You can use the 'removeNOPs' method to get rid + * off them. The resulting method object can be obtained via the 'getMethod()' method. * - * @see InstructionList - * @see Method - * @LastModified: May 2021 + * @see InstructionList + * @see Method + * @LastModified: Feb 2023 */ public class MethodGen extends FieldGenOrMethodGen { + static final class BranchStack { + + private final Stack branchTargets = new Stack<>(); + private final HashMap visitedTargets = new HashMap<>(); + + public BranchTarget pop() { + if (!branchTargets.empty()) { + return branchTargets.pop(); + } + return null; + } + + public void push(final InstructionHandle target, final int stackDepth) { + if (visited(target)) { + return; + } + branchTargets.push(visit(target, stackDepth)); + } + + private BranchTarget visit(final InstructionHandle target, final int stackDepth) { + final BranchTarget bt = new BranchTarget(target, stackDepth); + visitedTargets.put(target, bt); + return bt; + } + + private boolean visited(final InstructionHandle target) { + return visitedTargets.get(target) != null; + } + } + + static final class BranchTarget { + + final InstructionHandle target; + final int stackDepth; + + BranchTarget(final InstructionHandle target, final int stackDepth) { + this.target = target; + this.stackDepth = stackDepth; + } + } + + private static BCELComparator bcelComparator = new BCELComparator() { + + @Override + public boolean equals(final Object o1, final Object o2) { + final FieldGenOrMethodGen THIS = (FieldGenOrMethodGen) o1; + final FieldGenOrMethodGen THAT = (FieldGenOrMethodGen) o2; + return Objects.equals(THIS.getName(), THAT.getName()) && Objects.equals(THIS.getSignature(), THAT.getSignature()); + } + + @Override + public int hashCode(final Object o) { + final FieldGenOrMethodGen THIS = (FieldGenOrMethodGen) o; + return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); + } + }; + + private static byte[] getByteCodes(final Method method) { + final Code code = method.getCode(); + if (code == null) { + throw new IllegalStateException(String.format("The method '%s' has no code.", method)); + } + return code.getCode(); + } + + /** + * @return Comparison strategy object + */ + public static BCELComparator getComparator() { + return bcelComparator; + } + + /** + * Computes stack usage of an instruction list by performing control flow analysis. + * + * @return maximum stack depth used by method + */ + public static int getMaxStack(final ConstantPoolGen cp, final InstructionList il, final CodeExceptionGen[] et) { + final BranchStack branchTargets = new BranchStack(); + /* + * Initially, populate the branch stack with the exception handlers, because these aren't (necessarily) branched to + * explicitly. in each case, the stack will have depth 1, containing the exception object. + */ + for (final CodeExceptionGen element : et) { + final InstructionHandle handlerPc = element.getHandlerPC(); + if (handlerPc != null) { + branchTargets.push(handlerPc, 1); + } + } + int stackDepth = 0; + int maxStackDepth = 0; + InstructionHandle ih = il.getStart(); + while (ih != null) { + final Instruction instruction = ih.getInstruction(); + final short opcode = instruction.getOpcode(); + final int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); + stackDepth += delta; + if (stackDepth > maxStackDepth) { + maxStackDepth = stackDepth; + } + // choose the next instruction based on whether current is a branch. + if (instruction instanceof BranchInstruction) { + final BranchInstruction branch = (BranchInstruction) instruction; + if (instruction instanceof Select) { + // explore all of the select's targets. the default target is handled below. + final Select select = (Select) branch; + final InstructionHandle[] targets = select.getTargets(); + for (final InstructionHandle target : targets) { + branchTargets.push(target, stackDepth); + } + // nothing to fall through to. + ih = null; + } else if (!(branch instanceof IfInstruction)) { + // if an instruction that comes back to following PC, + // push next instruction, with stack depth reduced by 1. + if (opcode == Const.JSR || opcode == Const.JSR_W) { + branchTargets.push(ih.getNext(), stackDepth - 1); + } + ih = null; + } + // for all branches, the target of the branch is pushed on the branch stack. + // conditional branches have a fall through case, selects don't, and + // jsr/jsr_w return to the next instruction. + branchTargets.push(branch.getTarget(), stackDepth); + } else // check for instructions that terminate the method. + if (opcode == Const.ATHROW || opcode == Const.RET || opcode >= Const.IRETURN && opcode <= Const.RETURN) { + ih = null; + } + // normal case, go to the next instruction. + if (ih != null) { + ih = ih.getNext(); + } + // if we have no more instructions, see if there are any deferred branches to explore. + if (ih == null) { + final BranchTarget bt = branchTargets.pop(); + if (bt != null) { + ih = bt.target; + stackDepth = bt.stackDepth; + } + } + } + return maxStackDepth; + } + + /** + * @param comparator Comparison strategy object + */ + public static void setComparator(final BCELComparator comparator) { + bcelComparator = comparator; + } + private String className; private Type[] argTypes; private String[] argNames; private int maxLocals; private int maxStack; private InstructionList il; + private boolean stripAttributes; - private LocalVariableTypeTable localVariableTypeTable = null; + private LocalVariableTypeTable localVariableTypeTable; private final List variableList = new ArrayList<>(); + private final List lineNumberList = new ArrayList<>(); + private final List exceptionList = new ArrayList<>(); + private final List throwsList = new ArrayList<>(); + private final List codeAttrsList = new ArrayList<>(); private List[] paramAnnotations; // Array of lists containing AnnotationGen objects - private boolean hasParameterAnnotations = false; - private boolean haveUnpackedParameterAnnotations = false; - - private static BCELComparator bcelComparator = new BCELComparator() { - - @Override - public boolean equals( final Object o1, final Object o2 ) { - final MethodGen THIS = (MethodGen) o1; - final MethodGen THAT = (MethodGen) o2; - return Objects.equals(THIS.getName(), THAT.getName()) - && Objects.equals(THIS.getSignature(), THAT.getSignature()); - } + private boolean hasParameterAnnotations; - @Override - public int hashCode( final Object o ) { - final MethodGen THIS = (MethodGen) o; - return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); - } - }; + private boolean haveUnpackedParameterAnnotations; + private List observers; /** - * Declare method. If the method is non-static the constructor - * automatically declares a local variable `$this' in slot 0. The - * actual code is contained in the `il' parameter, which may further - * manipulated by the user. But he must take care not to remove any - * instruction (handles) that are still referenced from this object. + * Declare method. If the method is non-static the constructor automatically declares a local variable '$this' in slot + * 0. The actual code is contained in the 'il' parameter, which may further manipulated by the user. But they must take + * care not to remove any instruction (handles) that are still referenced from this object. * - * For example one may not add a local variable and later remove the - * instructions it refers to without causing havoc. It is safe - * however if you remove that local variable, too. + * For example one may not add a local variable and later remove the instructions it refers to without causing havoc. It + * is safe however if you remove that local variable, too. * - * @param access_flags access qualifiers - * @param return_type method type + * @param accessFlags access qualifiers + * @param returnType method type * @param argTypes argument types - * @param argNames argument names (if this is null, default names will be provided - * for them) - * @param method_name name of method + * @param argNames argument names (if this is null, default names will be provided for them) + * @param methodName name of method * @param className class name containing this method (may be null, if you don't care) - * @param il instruction list associated with this method, may be null only for - * abstract or native methods + * @param il instruction list associated with this method, may be null only for abstract or native methods * @param cp constant pool */ - public MethodGen(final int access_flags, final Type return_type, final Type[] argTypes, String[] argNames, - final String method_name, final String className, final InstructionList il, final ConstantPoolGen cp) { - super(access_flags); - setType(return_type); + public MethodGen(final int accessFlags, final Type returnType, final Type[] argTypes, String[] argNames, final String methodName, final String className, + final InstructionList il, final ConstantPoolGen cp) { + super(accessFlags); + setType(returnType); setArgumentTypes(argTypes); setArgumentNames(argNames); - setName(method_name); + setName(methodName); setClassName(className); setInstructionList(il); setConstantPool(cp); @@ -136,23 +272,23 @@ if (!abstract_) { start = il.getStart(); // end == null => live to end of method - /* Add local variables, namely the implicit `this' and the arguments + /* + * Add local variables, namely the implicit 'this' and the arguments */ - if (!isStatic() && (className != null)) { // Instance method -> `this' is local var 0 - addLocalVariable("this", ObjectType.getInstance(className), start, end); + if (!isStatic() && className != null) { // Instance method -> 'this' is local var 0 + addLocalVariable("this", ObjectType.getInstance(className), start, end); } } if (argTypes != null) { final int size = argTypes.length; - for (final Type arg_type : argTypes) { - if (Type.VOID == arg_type) { + for (final Type argType : argTypes) { + if (Type.VOID == argType) { throw new ClassGenException("'void' is an illegal argument type for a method"); } } if (argNames != null) { // Names for variables provided? if (size != argNames.length) { - throw new ClassGenException("Mismatch in argument array lengths: " + size - + " vs. " + argNames.length); + throw new ClassGenException("Mismatch in argument array lengths: " + size + " vs. " + argNames.length); } } else { // Give them dummy names argNames = new String[size]; @@ -169,7 +305,6 @@ } } - /** * Instantiate from existing method. * @@ -178,13 +313,10 @@ * @param cp constant pool */ public MethodGen(final Method method, final String className, final ConstantPoolGen cp) { - this(method.getAccessFlags(), Type.getReturnType(method.getSignature()), - Type.getArgumentTypes(method.getSignature()), null /* may be overridden anyway */ + this(method.getAccessFlags(), Type.getReturnType(method.getSignature()), Type.getArgumentTypes(method.getSignature()), + null /* may be overridden anyway */ , method.getName(), className, - ((method.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0) - ? new InstructionList(getByteCodes(method)) - : null, - cp); + (method.getAccessFlags() & (Const.ACC_ABSTRACT | Const.ACC_NATIVE)) == 0 ? new InstructionList(getByteCodes(method)) : null, cp); final Attribute[] attributes = method.getAttributes(); for (final Attribute attribute : attributes) { Attribute a = attribute; @@ -196,36 +328,33 @@ if (ces != null) { for (final CodeException ce : ces) { final int type = ce.getCatchType(); - ObjectType c_type = null; + ObjectType cType = null; if (type > 0) { - final String cen = method.getConstantPool().getConstantString(type, - Const.CONSTANT_Class); - c_type = ObjectType.getInstance(cen); + final String cen = method.getConstantPool().getConstantString(type, Const.CONSTANT_Class); + cType = ObjectType.getInstance(cen); } - final int end_pc = ce.getEndPC(); + final int endPc = ce.getEndPC(); final int length = getByteCodes(method).length; InstructionHandle end; - if (length == end_pc) { // May happen, because end_pc is exclusive + if (length == endPc) { // May happen, because end_pc is exclusive end = il.getEnd(); } else { - end = il.findHandle(end_pc); + end = il.findHandle(endPc); end = end.getPrev(); // Make it inclusive } - addExceptionHandler(il.findHandle(ce.getStartPC()), end, - il.findHandle(ce.getHandlerPC()), c_type); + addExceptionHandler(il.findHandle(ce.getStartPC()), end, il.findHandle(ce.getHandlerPC()), cType); } } - final Attribute[] c_attributes = c.getAttributes(); - for (final Attribute c_attribute : c_attributes) { - a = c_attribute; + final Attribute[] cAttributes = c.getAttributes(); + for (final Attribute cAttribute : cAttributes) { + a = cAttribute; if (a instanceof LineNumberTable) { - final LineNumber[] ln = ((LineNumberTable) a).getLineNumberTable(); - for (final LineNumber l : ln) { + ((LineNumberTable) a).forEach(l -> { final InstructionHandle ih = il.findHandle(l.getStartPC()); if (ih != null) { addLineNumber(ih, l.getLineNumber()); } - } + }); } else if (a instanceof LocalVariableTable) { updateLocalVariableTable((LocalVariableTable) a); } else if (a instanceof LocalVariableTypeTable) { @@ -235,474 +364,478 @@ } } } else if (a instanceof ExceptionTable) { - final String[] names = ((ExceptionTable) a).getExceptionNames(); - for (final String name2 : names) { - addException(name2); - } + Collections.addAll(throwsList, ((ExceptionTable) a).getExceptionNames()); } else if (a instanceof Annotations) { final Annotations runtimeAnnotations = (Annotations) a; - final AnnotationEntry[] aes = runtimeAnnotations.getAnnotationEntries(); - for (final AnnotationEntry element : aes) { - addAnnotationEntry(new AnnotationEntryGen(element, cp, false)); - } + runtimeAnnotations.forEach(element -> addAnnotationEntry(new AnnotationEntryGen(element, cp, false))); } else { addAttribute(a); } } } + /** + * @since 6.0 + */ + public void addAnnotationsAsAttribute(final ConstantPoolGen cp) { + addAll(AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries())); + } - private static byte[] getByteCodes(final Method method) { - final Code code = method.getCode(); - if (code == null) { - throw new IllegalStateException(String.format("The method '%s' has no code.", method)); + /** + * Add an attribute to the code. Currently, the JVM knows about the LineNumberTable, LocalVariableTable and StackMap + * attributes, where the former two will be generated automatically and the latter is used for the MIDP only. Other + * attributes will be ignored by the JVM but do no harm. + * + * @param a attribute to be added + */ + public void addCodeAttribute(final Attribute a) { + codeAttrsList.add(a); + } + + /** + * Add an exception possibly thrown by this method. + * + * @param className (fully qualified) name of exception + */ + public void addException(final String className) { + throwsList.add(className); + } + + /** + * Add an exception handler, i.e., specify region where a handler is active and an instruction where the actual handling + * is done. + * + * @param startPc Start of region (inclusive) + * @param endPc End of region (inclusive) + * @param handlerPc Where handling is done + * @param catchType class type of handled exception or null if any exception is handled + * @return new exception handler object + */ + public CodeExceptionGen addExceptionHandler(final InstructionHandle startPc, final InstructionHandle endPc, final InstructionHandle handlerPc, + final ObjectType catchType) { + if (startPc == null || endPc == null || handlerPc == null) { + throw new ClassGenException("Exception handler target is null instruction"); } - return code.getCode(); + final CodeExceptionGen c = new CodeExceptionGen(startPc, endPc, handlerPc, catchType); + exceptionList.add(c); + return c; } /** - * Adds a local variable to this method. + * Give an instruction a line number corresponding to the source code line. + * + * @param ih instruction to tag + * @return new line number object + * @see LineNumber + */ + public LineNumberGen addLineNumber(final InstructionHandle ih, final int srcLine) { + final LineNumberGen l = new LineNumberGen(ih, srcLine); + lineNumberList.add(l); + return l; + } + + /** + * Adds a local variable to this method and assigns an index automatically. * * @param name variable name * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 - * @param start from where the variable is valid - * @param end until where the variable is valid - * @param orig_index the index of the local variable prior to any modifications + * @param start from where the variable is valid, if this is null, it is valid from the start + * @param end until where the variable is valid, if this is null, it is valid to the end * @return new local variable object * @see LocalVariable */ - public LocalVariableGen addLocalVariable( final String name, final Type type, final int slot, - final InstructionHandle start, final InstructionHandle end, final int orig_index ) { - final byte t = type.getType(); - if (t != Const.T_ADDRESS) { - final int add = type.getSize(); - if (slot + add > maxLocals) { - maxLocals = slot + add; - } - final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end, orig_index); - int i; - if ((i = variableList.indexOf(l)) >= 0) { - variableList.set(i, l); - } else { - variableList.add(l); - } - return l; - } - throw new IllegalArgumentException("Can not use " + type - + " as type for local variable"); + public LocalVariableGen addLocalVariable(final String name, final Type type, final InstructionHandle start, final InstructionHandle end) { + return addLocalVariable(name, type, maxLocals, start, end); } - /** * Adds a local variable to this method. * * @param name variable name * @param type variable type - * @param slot the index of the local variable, if type is long or double, the next available - * index is slot+2 + * @param slot the index of the local variable, if type is long or double, the next available index is slot+2 * @param start from where the variable is valid * @param end until where the variable is valid * @return new local variable object * @see LocalVariable */ - public LocalVariableGen addLocalVariable( final String name, final Type type, final int slot, - final InstructionHandle start, final InstructionHandle end ) { + public LocalVariableGen addLocalVariable(final String name, final Type type, final int slot, final InstructionHandle start, final InstructionHandle end) { return addLocalVariable(name, type, slot, start, end, slot); } /** - * Adds a local variable to this method and assigns an index automatically. + * Adds a local variable to this method. * * @param name variable name * @param type variable type - * @param start from where the variable is valid, if this is null, - * it is valid from the start - * @param end until where the variable is valid, if this is null, - * it is valid to the end + * @param slot the index of the local variable, if type is long or double, the next available index is slot+2 + * @param start from where the variable is valid + * @param end until where the variable is valid + * @param origIndex the index of the local variable prior to any modifications * @return new local variable object * @see LocalVariable */ - public LocalVariableGen addLocalVariable( final String name, final Type type, final InstructionHandle start, - final InstructionHandle end ) { - return addLocalVariable(name, type, maxLocals, start, end); + public LocalVariableGen addLocalVariable(final String name, final Type type, final int slot, final InstructionHandle start, final InstructionHandle end, + final int origIndex) { + final byte t = type.getType(); + if (t != Const.T_ADDRESS) { + final int add = type.getSize(); + if (slot + add > maxLocals) { + maxLocals = slot + add; + } + final LocalVariableGen l = new LocalVariableGen(slot, name, type, start, end, origIndex); + int i; + if ((i = variableList.indexOf(l)) >= 0) { + variableList.set(i, l); + } else { + variableList.add(l); + } + return l; + } + throw new IllegalArgumentException("Can not use " + type + " as type for local variable"); } - /** - * Remove a local variable, its slot will not be reused, if you do not use - * addLocalVariable with an explicit index argument. + * Add observer for this object. */ - public void removeLocalVariable(final LocalVariableGen l) { - variableList.remove(l); + public void addObserver(final MethodObserver o) { + if (observers == null) { + observers = new ArrayList<>(); + } + observers.add(o); } - - /** - * Remove all local variables. - */ - public void removeLocalVariables() { - variableList.clear(); - } - - - /* - * If the range of the variable has not been set yet, it will be set to be valid from - * the start to the end of the instruction list. - * - * @return array of declared local variables sorted by index - */ - public LocalVariableGen[] getLocalVariables() { - final int size = variableList.size(); - final LocalVariableGen[] lg = new LocalVariableGen[size]; - variableList.toArray(lg); - for (int i = 0; i < size; i++) { - if ((lg[i].getStart() == null) && (il != null)) { - lg[i].setStart(il.getStart()); - } - if ((lg[i].getEnd() == null) && (il != null)) { - lg[i].setEnd(il.getEnd()); - } + public void addParameterAnnotation(final int parameterIndex, final AnnotationEntryGen annotation) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations) { + @SuppressWarnings({"rawtypes", "unchecked"}) + final List[] parmList = (List[])new List[argTypes.length]; + paramAnnotations = parmList; + hasParameterAnnotations = true; } - if (size > 1) { - Arrays.sort(lg, (o1, o2) -> o1.getIndex() - o2.getIndex()); + final List existingAnnotations = paramAnnotations[parameterIndex]; + if (existingAnnotations != null) { + existingAnnotations.add(annotation); + } else { + final List l = new ArrayList<>(); + l.add(annotation); + paramAnnotations[parameterIndex] = l; } - return lg; } - /** - * @return `LocalVariableTable' attribute of all the local variables of this method. + * @since 6.0 */ - public LocalVariableTable getLocalVariableTable( final ConstantPoolGen cp ) { - final LocalVariableGen[] lg = getLocalVariables(); - final int size = lg.length; - final LocalVariable[] lv = new LocalVariable[size]; - for (int i = 0; i < size; i++) { - lv[i] = lg[i].getLocalVariable(cp); + public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { + if (!hasParameterAnnotations) { + return; + } + final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, paramAnnotations); + if (attrs != null) { + addAll(attrs); } - return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp - .getConstantPool()); } - /** - * @return `LocalVariableTypeTable' attribute of this method. - */ - public LocalVariableTypeTable getLocalVariableTypeTable() { - return localVariableTypeTable; + private Attribute[] addRuntimeAnnotationsAsAttribute(final ConstantPoolGen cp) { + final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); + addAll(attrs); + return attrs; } - /** - * Give an instruction a line number corresponding to the source code line. - * - * @param ih instruction to tag - * @return new line number object - * @see LineNumber - */ - public LineNumberGen addLineNumber( final InstructionHandle ih, final int srcLine ) { - final LineNumberGen l = new LineNumberGen(ih, srcLine); - lineNumberList.add(l); - return l; + private Attribute[] addRuntimeParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { + if (!hasParameterAnnotations) { + return Attribute.EMPTY_ARRAY; + } + final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, paramAnnotations); + addAll(attrs); + return attrs; } - - /** - * Remove a line number. - */ - public void removeLineNumber( final LineNumberGen l ) { - lineNumberList.remove(l); + private void adjustLocalVariableTypeTable(final LocalVariableTable lvt) { + final LocalVariable[] lv = lvt.getLocalVariableTable(); + for (final LocalVariable element : localVariableTypeTable.getLocalVariableTypeTable()) { + for (final LocalVariable l : lv) { + if (element.getName().equals(l.getName()) && element.getIndex() == l.getOrigIndex()) { + element.setLength(l.getLength()); + element.setStartPC(l.getStartPC()); + element.setIndex(l.getIndex()); + break; + } + } + } } - /** - * Remove all line numbers. - */ - public void removeLineNumbers() { - lineNumberList.clear(); - } - - - /* - * @return array of line numbers + * @return deep copy of this method */ - public LineNumberGen[] getLineNumbers() { - final LineNumberGen[] lg = new LineNumberGen[lineNumberList.size()]; - lineNumberList.toArray(lg); - return lg; + public MethodGen copy(final String className, final ConstantPoolGen cp) { + final Method m = ((MethodGen) clone()).getMethod(); + final MethodGen mg = new MethodGen(m, className, super.getConstantPool()); + if (super.getConstantPool() != cp) { + mg.setConstantPool(cp); + mg.getInstructionList().replaceConstantPool(super.getConstantPool(), cp); + } + return mg; } - /** - * @return `LineNumberTable' attribute of all the local variables of this method. + * Goes through the attributes on the method and identifies any that are RuntimeParameterAnnotations, extracting their + * contents and storing them as parameter annotations. There are two kinds of parameter annotation - visible and + * invisible. Once they have been unpacked, these attributes are deleted. (The annotations will be rebuilt as attributes + * when someone builds a Method object out of this MethodGen object). */ - public LineNumberTable getLineNumberTable( final ConstantPoolGen cp ) { - final int size = lineNumberList.size(); - final LineNumber[] ln = new LineNumber[size]; - for (int i = 0; i < size; i++) { - ln[i] = lineNumberList.get(i).getLineNumber(); + private void ensureExistingParameterAnnotationsUnpacked() { + if (haveUnpackedParameterAnnotations) { + return; + } + // Find attributes that contain parameter annotation data + final Attribute[] attrs = getAttributes(); + ParameterAnnotations paramAnnVisAttr = null; + ParameterAnnotations paramAnnInvisAttr = null; + for (final Attribute attribute : attrs) { + if (attribute instanceof ParameterAnnotations) { + // Initialize paramAnnotations + if (!hasParameterAnnotations) { + @SuppressWarnings({"rawtypes", "unchecked"}) + final List[] parmList = (List[])new List[argTypes.length]; + paramAnnotations = parmList; + Arrays.setAll(paramAnnotations, i -> new ArrayList<>()); + } + hasParameterAnnotations = true; + final ParameterAnnotations rpa = (ParameterAnnotations) attribute; + if (rpa instanceof RuntimeVisibleParameterAnnotations) { + paramAnnVisAttr = rpa; + } else { + paramAnnInvisAttr = rpa; + } + final ParameterAnnotationEntry[] parameterAnnotationEntries = rpa.getParameterAnnotationEntries(); + for (int j = 0; j < parameterAnnotationEntries.length; j++) { + // This returns Annotation[] ... + final ParameterAnnotationEntry immutableArray = rpa.getParameterAnnotationEntries()[j]; + // ... which needs transforming into an AnnotationGen[] ... + final List mutable = makeMutableVersion(immutableArray.getAnnotationEntries()); + // ... then add these to any we already know about + paramAnnotations[j].addAll(mutable); + } + } + } + if (paramAnnVisAttr != null) { + removeAttribute(paramAnnVisAttr); + } + if (paramAnnInvisAttr != null) { + removeAttribute(paramAnnInvisAttr); } - return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp - .getConstantPool()); + haveUnpackedParameterAnnotations = true; } - /** - * Add an exception handler, i.e., specify region where a handler is active and an - * instruction where the actual handling is done. + * Return value as defined by given BCELComparator strategy. By default two MethodGen objects are said to be equal when + * their names and signatures are equal. * - * @param start_pc Start of region (inclusive) - * @param end_pc End of region (inclusive) - * @param handler_pc Where handling is done - * @param catch_type class type of handled exception or null if any - * exception is handled - * @return new exception handler object + * @see Object#equals(Object) */ - public CodeExceptionGen addExceptionHandler( final InstructionHandle start_pc, - final InstructionHandle end_pc, final InstructionHandle handler_pc, final ObjectType catch_type ) { - if ((start_pc == null) || (end_pc == null) || (handler_pc == null)) { - throw new ClassGenException("Exception handler target is null instruction"); - } - final CodeExceptionGen c = new CodeExceptionGen(start_pc, end_pc, handler_pc, catch_type); - exceptionList.add(c); - return c; + @Override + public boolean equals(final Object obj) { + return bcelComparator.equals(this, obj); } - + // J5TODO: Should paramAnnotations be an array of arrays? Rather than an array of lists, this + // is more likely to suggest to the caller it is readonly (which a List does not). /** - * Remove an exception handler. + * Return a list of AnnotationGen objects representing parameter annotations + * + * @since 6.0 */ - public void removeExceptionHandler( final CodeExceptionGen c ) { - exceptionList.remove(c); + public List getAnnotationsOnParameter(final int i) { + ensureExistingParameterAnnotationsUnpacked(); + if (!hasParameterAnnotations || i > argTypes.length) { + return null; + } + return paramAnnotations[i]; } - - /** - * Remove all line numbers. - */ - public void removeExceptionHandlers() { - exceptionList.clear(); + public String getArgumentName(final int i) { + return argNames[i]; } + public String[] getArgumentNames() { + return argNames.clone(); + } - /* - * @return array of declared exception handlers - */ - public CodeExceptionGen[] getExceptionHandlers() { - final CodeExceptionGen[] cg = new CodeExceptionGen[exceptionList.size()]; - exceptionList.toArray(cg); - return cg; + public Type getArgumentType(final int i) { + return argTypes[i]; } + public Type[] getArgumentTypes() { + return argTypes.clone(); + } /** - * @return code exceptions for `Code' attribute + * @return class that contains this method */ - private CodeException[] getCodeExceptions() { - final int size = exceptionList.size(); - final CodeException[] c_exc = new CodeException[size]; - for (int i = 0; i < size; i++) { - final CodeExceptionGen c = exceptionList.get(i); - c_exc[i] = c.getCodeException(super.getConstantPool()); - } - return c_exc; + public String getClassName() { + return className; } - /** - * Add an exception possibly thrown by this method. - * - * @param className (fully qualified) name of exception + * @return all attributes of this method. */ - public void addException( final String className ) { - throwsList.add(className); + public Attribute[] getCodeAttributes() { + return codeAttrsList.toArray(Attribute.EMPTY_ARRAY); } - /** - * Remove an exception. + * @return code exceptions for 'Code' attribute */ - public void removeException( final String c ) { - throwsList.remove(c); + private CodeException[] getCodeExceptions() { + final int size = exceptionList.size(); + final CodeException[] cExc = new CodeException[size]; + Arrays.setAll(cExc, i -> exceptionList.get(i).getCodeException(super.getConstantPool())); + return cExc; } - - /** - * Remove all exceptions. + /* + * @return array of declared exception handlers */ - public void removeExceptions() { - throwsList.clear(); + public CodeExceptionGen[] getExceptionHandlers() { + return exceptionList.toArray(CodeExceptionGen.EMPTY_ARRAY); } - /* * @return array of thrown exceptions */ public String[] getExceptions() { - return throwsList.toArray(new String[0]); + return throwsList.toArray(Const.EMPTY_STRING_ARRAY); } - /** - * @return `Exceptions' attribute of all the exceptions thrown by this method. + * @return 'Exceptions' attribute of all the exceptions thrown by this method. */ - private ExceptionTable getExceptionTable( final ConstantPoolGen cp ) { + private ExceptionTable getExceptionTable(final ConstantPoolGen cp) { final int size = throwsList.size(); final int[] ex = new int[size]; - for (int i = 0; i < size; i++) { - ex[i] = cp.addClass(throwsList.get(i)); - } + Arrays.setAll(ex, i -> cp.addClass(throwsList.get(i))); return new ExceptionTable(cp.addUtf8("Exceptions"), 2 + 2 * size, ex, cp.getConstantPool()); } + public InstructionList getInstructionList() { + return il; + } - /** - * Add an attribute to the code. Currently, the JVM knows about the - * LineNumberTable, LocalVariableTable and StackMap attributes, - * where the former two will be generated automatically and the - * latter is used for the MIDP only. Other attributes will be - * ignored by the JVM but do no harm. - * - * @param a attribute to be added + /* + * @return array of line numbers */ - public void addCodeAttribute( final Attribute a ) { - codeAttrsList.add(a); + public LineNumberGen[] getLineNumbers() { + return lineNumberList.toArray(LineNumberGen.EMPTY_ARRAY); } - /** - * Remove the LocalVariableTypeTable + * @return 'LineNumberTable' attribute of all the local variables of this method. */ - public void removeLocalVariableTypeTable( ) { - localVariableTypeTable = null; + public LineNumberTable getLineNumberTable(final ConstantPoolGen cp) { + final int size = lineNumberList.size(); + final LineNumber[] ln = new LineNumber[size]; + Arrays.setAll(ln, i -> lineNumberList.get(i).getLineNumber()); + return new LineNumberTable(cp.addUtf8("LineNumberTable"), 2 + ln.length * 4, ln, cp.getConstantPool()); } - /** - * Remove a code attribute. + /* + * If the range of the variable has not been set yet, it will be set to be valid from the start to the end of the + * instruction list. + * + * @return array of declared local variables sorted by index */ - public void removeCodeAttribute( final Attribute a ) { - codeAttrsList.remove(a); + public LocalVariableGen[] getLocalVariables() { + final int size = variableList.size(); + final LocalVariableGen[] lg = new LocalVariableGen[size]; + variableList.toArray(lg); + for (int i = 0; i < size; i++) { + if (lg[i].getStart() == null && il != null) { + lg[i].setStart(il.getStart()); + } + if (lg[i].getEnd() == null && il != null) { + lg[i].setEnd(il.getEnd()); + } + } + if (size > 1) { + Arrays.sort(lg, Comparator.comparingInt(LocalVariableGen::getIndex)); + } + return lg; } - /** - * Remove all code attributes. + * @return 'LocalVariableTable' attribute of all the local variables of this method. */ - public void removeCodeAttributes() { - localVariableTypeTable = null; - codeAttrsList.clear(); + public LocalVariableTable getLocalVariableTable(final ConstantPoolGen cp) { + final LocalVariableGen[] lg = getLocalVariables(); + final int size = lg.length; + final LocalVariable[] lv = new LocalVariable[size]; + Arrays.setAll(lv, i -> lg[i].getLocalVariable(cp)); + return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp.getConstantPool()); } - /** - * @return all attributes of this method. + * @return 'LocalVariableTypeTable' attribute of this method. */ - public Attribute[] getCodeAttributes() { - return codeAttrsList.toArray(new Attribute[0]); + public LocalVariableTypeTable getLocalVariableTypeTable() { + return localVariableTypeTable; } - /** - * @since 6.0 - */ - public void addAnnotationsAsAttribute(final ConstantPoolGen cp) { - final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); - for (final Attribute attr : attrs) { - addAttribute(attr); - } - } - - /** - * @since 6.0 - */ - public void addParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { - if (!hasParameterAnnotations) { - return; - } - final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, paramAnnotations); - if (attrs != null) { - for (final Attribute attr : attrs) { - addAttribute(attr); - } - } - } - - private Attribute[] addRuntimeAnnotationsAsAttribute(final ConstantPoolGen cp) { - final Attribute[] attrs = AnnotationEntryGen.getAnnotationAttributes(cp, super.getAnnotationEntries()); - for (final Attribute attr : attrs) { - addAttribute(attr); - } - return attrs; - } - - private Attribute[] addRuntimeParameterAnnotationsAsAttribute(final ConstantPoolGen cp) { - if (!hasParameterAnnotations) { - return new Attribute[0]; - } - final Attribute[] attrs = AnnotationEntryGen.getParameterAnnotationAttributes(cp, paramAnnotations); - for (final Attribute attr : attrs) { - addAttribute(attr); - } - return attrs; + public int getMaxLocals() { + return maxLocals; } - /** - * Would prefer to make this private, but need a way to test if client is - * using BCEL version 6.5.0 or later that contains fix for BCEL-329. - * @since 6.5.0 - */ - public void removeRuntimeAttributes(final Attribute[] attrs) { - for (final Attribute attr : attrs) { - removeAttribute(attr); - } + public int getMaxStack() { + return maxStack; } - /** - * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, - * before calling this method (the same applies for max locals). + * Get method object. Never forget to call setMaxStack() or setMaxStack(max), respectively, before calling this method + * (the same applies for max locals). * * @return method object */ public Method getMethod() { final String signature = getSignature(); - final ConstantPoolGen _cp = super.getConstantPool(); - final int name_index = _cp.addUtf8(super.getName()); - final int signature_index = _cp.addUtf8(signature); - /* Also updates positions of instructions, i.e., their indices + final ConstantPoolGen cp = super.getConstantPool(); + final int nameIndex = cp.addUtf8(super.getName()); + final int signatureIndex = cp.addUtf8(signature); + /* + * Also updates positions of instructions, i.e., their indices */ - byte[] byte_code = null; - if (il != null) { - byte_code = il.getByteCode(); - } + final byte[] byteCode = il != null ? il.getByteCode() : null; LineNumberTable lnt = null; LocalVariableTable lvt = null; - /* Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) + /* + * Create LocalVariableTable and LineNumberTable attributes (for debuggers, e.g.) */ - if ((variableList.size() > 0) && !stripAttributes) { - updateLocalVariableTable(getLocalVariableTable(_cp)); - addCodeAttribute(lvt = getLocalVariableTable(_cp)); + if (!variableList.isEmpty() && !stripAttributes) { + updateLocalVariableTable(getLocalVariableTable(cp)); + addCodeAttribute(lvt = getLocalVariableTable(cp)); } if (localVariableTypeTable != null) { - // LocalVariable length in LocalVariableTypeTable is not updated automatically. It's a difference with LocalVariableTable. + // LocalVariable length in LocalVariableTypeTable is not updated automatically. It's a difference with + // LocalVariableTable. if (lvt != null) { adjustLocalVariableTypeTable(lvt); } addCodeAttribute(localVariableTypeTable); } - if ((lineNumberList.size() > 0) && !stripAttributes) { - addCodeAttribute(lnt = getLineNumberTable(_cp)); + if (!lineNumberList.isEmpty() && !stripAttributes) { + addCodeAttribute(lnt = getLineNumberTable(cp)); } - final Attribute[] code_attrs = getCodeAttributes(); - /* Each attribute causes 6 additional header bytes + final Attribute[] codeAttrs = getCodeAttributes(); + /* + * Each attribute causes 6 additional header bytes */ - int attrs_len = 0; - for (final Attribute code_attr : code_attrs) { - attrs_len += code_attr.getLength() + 6; + int attrsLen = 0; + for (final Attribute codeAttr : codeAttrs) { + attrsLen += codeAttr.getLength() + 6; } - final CodeException[] c_exc = getCodeExceptions(); - final int exc_len = c_exc.length * 8; // Every entry takes 8 bytes + final CodeException[] cExc = getCodeExceptions(); + final int excLen = cExc.length * 8; // Every entry takes 8 bytes Code code = null; - if ((il != null) && !isAbstract() && !isNative()) { + if (byteCode != null && !isAbstract() && !isNative()) { // Remove any stale code attribute final Attribute[] attributes = getAttributes(); for (final Attribute a : attributes) { @@ -710,21 +843,20 @@ removeAttribute(a); } } - code = new Code(_cp.addUtf8("Code"), 8 + byte_code.length + // prologue byte code - 2 + exc_len + // exceptions - 2 + attrs_len, // attributes - maxStack, maxLocals, byte_code, c_exc, code_attrs, _cp.getConstantPool()); + code = new Code(cp.addUtf8("Code"), 8 + byteCode.length + // prologue byte code + 2 + excLen + // exceptions + 2 + attrsLen, // attributes + maxStack, maxLocals, byteCode, cExc, codeAttrs, cp.getConstantPool()); addAttribute(code); } - final Attribute[] annotations = addRuntimeAnnotationsAsAttribute(_cp); - final Attribute[] parameterAnnotations = addRuntimeParameterAnnotationsAsAttribute(_cp); + final Attribute[] annotations = addRuntimeAnnotationsAsAttribute(cp); + final Attribute[] parameterAnnotations = addRuntimeParameterAnnotationsAsAttribute(cp); ExceptionTable et = null; - if (throwsList.size() > 0) { - addAttribute(et = getExceptionTable(_cp)); - // Add `Exceptions' if there are "throws" clauses + if (!throwsList.isEmpty()) { + addAttribute(et = getExceptionTable(cp)); + // Add 'Exceptions' if there are "throws" clauses } - final Method m = new Method(super.getAccessFlags(), name_index, signature_index, getAttributes(), _cp - .getConstantPool()); + final Method m = new Method(super.getAccessFlags(), nameIndex, signatureIndex, getAttributes(), cp.getConstantPool()); // Undo effects of adding attributes if (lvt != null) { removeCodeAttribute(lvt); @@ -746,185 +878,185 @@ return m; } - private void updateLocalVariableTable(final LocalVariableTable a) { - final LocalVariable[] lv = a.getLocalVariableTable(); - removeLocalVariables(); - for (final LocalVariable l : lv) { - InstructionHandle start = il.findHandle(l.getStartPC()); - final InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); - // Repair malformed handles - if (null == start) { - start = il.getStart(); - } - // end == null => live to end of method - // Since we are recreating the LocalVaraible, we must - // propagate the orig_index to new copy. - addLocalVariable(l.getName(), Type.getType(l.getSignature()), l - .getIndex(), start, end, l.getOrigIndex()); - } + public Type getReturnType() { + return getType(); } - private void adjustLocalVariableTypeTable(final LocalVariableTable lvt) { - final LocalVariable[] lv = lvt.getLocalVariableTable(); - final LocalVariable[] lvg = localVariableTypeTable.getLocalVariableTypeTable(); - - for (final LocalVariable element : lvg) { - for (final LocalVariable l : lv) { - if (element.getName().equals(l.getName()) && element.getIndex() == l.getOrigIndex()) { - element.setLength(l.getLength()); - element.setStartPC(l.getStartPC()); - element.setIndex(l.getIndex()); - break; - } - } - } + @Override + public String getSignature() { + return Type.getMethodSignature(super.getType(), argTypes); } - /** - * Remove all NOPs from the instruction list (if possible) and update every - * object referring to them, i.e., branch instructions, local variables and - * exception handlers. + * Return value as defined by given BCELComparator strategy. By default return the hashcode of the method's name XOR + * signature. + * + * @see Object#hashCode() */ - public void removeNOPs() { - if (il != null) { - InstructionHandle next; - /* Check branch instructions. - */ - for (InstructionHandle ih = il.getStart(); ih != null; ih = next) { - next = ih.getNext(); - if ((next != null) && (ih.getInstruction() instanceof NOP)) { - try { - il.delete(ih); - } catch (final TargetLostException e) { - for (final InstructionHandle target : e.getTargets()) { - for (final InstructionTargeter targeter : target.getTargeters()) { - targeter.updateTarget(target, next); - } - } - } - } - } - } + @Override + public int hashCode() { + return bcelComparator.hashCode(this); } + private List makeMutableVersion(final AnnotationEntry[] mutableArray) { + final List result = new ArrayList<>(); + for (final AnnotationEntry element : mutableArray) { + result.add(new AnnotationEntryGen(element, getConstantPool(), false)); + } + return result; + } /** - * Set maximum number of local variables. + * Remove a code attribute. */ - public void setMaxLocals( final int m ) { - maxLocals = m; + public void removeCodeAttribute(final Attribute a) { + codeAttrsList.remove(a); } - - public int getMaxLocals() { - return maxLocals; + /** + * Remove all code attributes. + */ + public void removeCodeAttributes() { + localVariableTypeTable = null; + codeAttrsList.clear(); } - /** - * Set maximum stack size for this method. + * Remove an exception. */ - public void setMaxStack( final int m ) { // TODO could be package-protected? - maxStack = m; + public void removeException(final String c) { + throwsList.remove(c); } - - public int getMaxStack() { - return maxStack; + /** + * Remove an exception handler. + */ + public void removeExceptionHandler(final CodeExceptionGen c) { + exceptionList.remove(c); } - - /** @return class that contains this method + /** + * Remove all line numbers. */ - public String getClassName() { - return className; + public void removeExceptionHandlers() { + exceptionList.clear(); } - - public void setClassName( final String class_name ) { // TODO could be package-protected? - this.className = class_name; + /** + * Remove all exceptions. + */ + public void removeExceptions() { + throwsList.clear(); } - - public void setReturnType( final Type return_type ) { - setType(return_type); + /** + * Remove a line number. + */ + public void removeLineNumber(final LineNumberGen l) { + lineNumberList.remove(l); } - - public Type getReturnType() { - return getType(); + /** + * Remove all line numbers. + */ + public void removeLineNumbers() { + lineNumberList.clear(); } - - public void setArgumentTypes( final Type[] arg_types ) { - this.argTypes = arg_types; + /** + * Remove a local variable, its slot will not be reused, if you do not use addLocalVariable with an explicit index + * argument. + */ + public void removeLocalVariable(final LocalVariableGen l) { + variableList.remove(l); } - - public Type[] getArgumentTypes() { - return argTypes.clone(); + /** + * Remove all local variables. + */ + public void removeLocalVariables() { + variableList.clear(); } - - public void setArgumentType( final int i, final Type type ) { - argTypes[i] = type; + /** + * Remove the LocalVariableTypeTable + */ + public void removeLocalVariableTypeTable() { + localVariableTypeTable = null; } - - public Type getArgumentType( final int i ) { - return argTypes[i]; + /** + * Remove all NOPs from the instruction list (if possible) and update every object referring to them, i.e., branch + * instructions, local variables and exception handlers. + */ + public void removeNOPs() { + if (il != null) { + InstructionHandle next; + /* + * Check branch instructions. + */ + for (InstructionHandle ih = il.getStart(); ih != null; ih = next) { + next = ih.getNext(); + if (next != null && ih.getInstruction() instanceof NOP) { + try { + il.delete(ih); + } catch (final TargetLostException e) { + for (final InstructionHandle target : e.getTargets()) { + for (final InstructionTargeter targeter : target.getTargeters()) { + targeter.updateTarget(target, next); + } + } + } + } + } + } } - - public void setArgumentNames( final String[] arg_names ) { - this.argNames = arg_names; + /** + * Remove observer for this object. + */ + public void removeObserver(final MethodObserver o) { + if (observers != null) { + observers.remove(o); + } } - - public String[] getArgumentNames() { - return argNames.clone(); + /** + * Would prefer to make this private, but need a way to test if client is using BCEL version 6.5.0 or later that + * contains fix for BCEL-329. + * + * @since 6.5.0 + */ + public void removeRuntimeAttributes(final Attribute[] attrs) { + for (final Attribute attr : attrs) { + removeAttribute(attr); + } } - - public void setArgumentName( final int i, final String name ) { + public void setArgumentName(final int i, final String name) { argNames[i] = name; } - - public String getArgumentName( final int i ) { - return argNames[i]; + public void setArgumentNames(final String[] argNames) { + this.argNames = argNames; } - - public InstructionList getInstructionList() { - return il; + public void setArgumentType(final int i, final Type type) { + argTypes[i] = type; } - - public void setInstructionList( final InstructionList il ) { // TODO could be package-protected? - this.il = il; + public void setArgumentTypes(final Type[] argTypes) { + this.argTypes = argTypes; } - - @Override - public String getSignature() { - return Type.getMethodSignature(super.getType(), argTypes); + public void setClassName(final String className) { // TODO could be package-protected? + this.className = className; } - - /** - * Computes max. stack size by performing control flow analysis. - */ - public void setMaxStack() { // TODO could be package-protected? (some tests would need repackaging) - if (il != null) { - maxStack = getMaxStack(super.getConstantPool(), il, getExceptionHandlers()); - } else { - maxStack = 0; - } + public void setInstructionList(final InstructionList il) { // TODO could be package-protected? + this.il = il; } - /** * Compute maximum number of local variables. */ @@ -932,16 +1064,14 @@ if (il != null) { int max = isStatic() ? 0 : 1; if (argTypes != null) { - for (final Type arg_type : argTypes) { - max += arg_type.getSize(); + for (final Type argType : argTypes) { + max += argType.getSize(); } } for (InstructionHandle ih = il.getStart(); ih != null; ih = ih.getNext()) { final Instruction ins = ih.getInstruction(); - if ((ins instanceof LocalVariableInstruction) || (ins instanceof RET) - || (ins instanceof IINC)) { - final int index = ((IndexedInstruction) ins).getIndex() - + ((TypedInstruction) ins).getType(super.getConstantPool()).getSize(); + if (ins instanceof LocalVariableInstruction || ins instanceof RET || ins instanceof IINC) { + final int index = ((IndexedInstruction) ins).getIndex() + ((TypedInstruction) ins).getType(super.getConstantPool()).getSize(); if (index > max) { max = index; } @@ -953,176 +1083,45 @@ } } - - /** Do not/Do produce attributes code attributesLineNumberTable and - * LocalVariableTable, like javac -O + /** + * Set maximum number of local variables. */ - public void stripAttributes( final boolean flag ) { - stripAttributes = flag; - } - - static final class BranchTarget { - - final InstructionHandle target; - final int stackDepth; - - - BranchTarget(final InstructionHandle target, final int stackDepth) { - this.target = target; - this.stackDepth = stackDepth; - } - } - - static final class BranchStack { - - private final Stack branchTargets = new Stack<>(); - private final Map visitedTargets = new HashMap<>(); - - - public void push( final InstructionHandle target, final int stackDepth ) { - if (visited(target)) { - return; - } - branchTargets.push(visit(target, stackDepth)); - } - - - public BranchTarget pop() { - if (!branchTargets.empty()) { - final BranchTarget bt = branchTargets.pop(); - return bt; - } - return null; - } - - - private BranchTarget visit( final InstructionHandle target, final int stackDepth ) { - final BranchTarget bt = new BranchTarget(target, stackDepth); - visitedTargets.put(target, bt); - return bt; - } - - - private boolean visited( final InstructionHandle target ) { - return visitedTargets.get(target) != null; - } + public void setMaxLocals(final int m) { + maxLocals = m; } - /** - * Computes stack usage of an instruction list by performing control flow analysis. - * - * @return maximum stack depth used by method + * Computes max. stack size by performing control flow analysis. */ - public static int getMaxStack( final ConstantPoolGen cp, final InstructionList il, final CodeExceptionGen[] et ) { - final BranchStack branchTargets = new BranchStack(); - /* Initially, populate the branch stack with the exception - * handlers, because these aren't (necessarily) branched to - * explicitly. in each case, the stack will have depth 1, - * containing the exception object. - */ - for (final CodeExceptionGen element : et) { - final InstructionHandle handler_pc = element.getHandlerPC(); - if (handler_pc != null) { - branchTargets.push(handler_pc, 1); - } - } - int stackDepth = 0; - int maxStackDepth = 0; - InstructionHandle ih = il.getStart(); - while (ih != null) { - final Instruction instruction = ih.getInstruction(); - final short opcode = instruction.getOpcode(); - final int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); - stackDepth += delta; - if (stackDepth > maxStackDepth) { - maxStackDepth = stackDepth; - } - // choose the next instruction based on whether current is a branch. - if (instruction instanceof BranchInstruction) { - final BranchInstruction branch = (BranchInstruction) instruction; - if (instruction instanceof Select) { - // explore all of the select's targets. the default target is handled below. - final Select select = (Select) branch; - final InstructionHandle[] targets = select.getTargets(); - for (final InstructionHandle target : targets) { - branchTargets.push(target, stackDepth); - } - // nothing to fall through to. - ih = null; - } else if (!(branch instanceof IfInstruction)) { - // if an instruction that comes back to following PC, - // push next instruction, with stack depth reduced by 1. - if (opcode == Const.JSR || opcode == Const.JSR_W) { - branchTargets.push(ih.getNext(), stackDepth - 1); - } - ih = null; - } - // for all branches, the target of the branch is pushed on the branch stack. - // conditional branches have a fall through case, selects don't, and - // jsr/jsr_w return to the next instruction. - branchTargets.push(branch.getTarget(), stackDepth); - } else { - // check for instructions that terminate the method. - if (opcode == Const.ATHROW || opcode == Const.RET - || (opcode >= Const.IRETURN && opcode <= Const.RETURN)) { - ih = null; - } - } - // normal case, go to the next instruction. - if (ih != null) { - ih = ih.getNext(); - } - // if we have no more instructions, see if there are any deferred branches to explore. - if (ih == null) { - final BranchTarget bt = branchTargets.pop(); - if (bt != null) { - ih = bt.target; - stackDepth = bt.stackDepth; - } - } + public void setMaxStack() { // TODO could be package-protected? (some tests would need repackaging) + if (il != null) { + maxStack = getMaxStack(super.getConstantPool(), il, getExceptionHandlers()); + } else { + maxStack = 0; } - return maxStackDepth; } - private List observers; - - - /** Add observer for this object. + /** + * Set maximum stack size for this method. */ - public void addObserver( final MethodObserver o ) { - if (observers == null) { - observers = new ArrayList<>(); - } - observers.add(o); + public void setMaxStack(final int m) { // TODO could be package-protected? + maxStack = m; } - - /** Remove observer for this object. - */ - public void removeObserver( final MethodObserver o ) { - if (observers != null) { - observers.remove(o); - } + public void setReturnType(final Type returnType) { + setType(returnType); } - - /** Call notify() method on all observers. This method is not called - * automatically whenever the state has changed, but has to be - * called by the user after he has finished editing the object. + /** + * Do not/Do produce attributes code attributesLineNumberTable and LocalVariableTable, like javac -O */ - public void update() { - if (observers != null) { - for (final MethodObserver observer : observers) { - observer.notify(this); - } - } + public void stripAttributes(final boolean flag) { + stripAttributes = flag; } - /** - * Return string representation close to declaration format, - * `public static void main(String[]) throws IOException', e.g. + * Return string representation close to declaration format, 'public static void main(String[]) throws IOException', + * e.g. * * @return String representation of the method. */ @@ -1130,16 +1129,15 @@ public final String toString() { final String access = Utility.accessToString(super.getAccessFlags()); String signature = Type.getMethodSignature(super.getType(), argTypes); - signature = Utility.methodSignatureToString(signature, super.getName(), access, true, - getLocalVariableTable(super.getConstantPool())); + signature = Utility.methodSignatureToString(signature, super.getName(), access, true, getLocalVariableTable(super.getConstantPool())); final StringBuilder buf = new StringBuilder(signature); for (final Attribute a : getAttributes()) { - if (!((a instanceof Code) || (a instanceof ExceptionTable))) { + if (!(a instanceof Code || a instanceof ExceptionTable)) { buf.append(" [").append(a).append("]"); } } - if (throwsList.size() > 0) { + if (!throwsList.isEmpty()) { for (final String throwsDescriptor : throwsList) { buf.append("\n\t\tthrows ").append(throwsDescriptor); } @@ -1147,162 +1145,31 @@ return buf.toString(); } - - /** @return deep copy of this method - */ - public MethodGen copy( final String className, final ConstantPoolGen cp ) { - final Method m = ((MethodGen) clone()).getMethod(); - final MethodGen mg = new MethodGen(m, className, super.getConstantPool()); - if (super.getConstantPool() != cp) { - mg.setConstantPool(cp); - mg.getInstructionList().replaceConstantPool(super.getConstantPool(), cp); - } - return mg; - } - - //J5TODO: Should paramAnnotations be an array of arrays? Rather than an array of lists, this - // is more likely to suggest to the caller it is readonly (which a List does not). - /** - * Return a list of AnnotationGen objects representing parameter annotations - * @since 6.0 - */ - public List getAnnotationsOnParameter(final int i) { - ensureExistingParameterAnnotationsUnpacked(); - if (!hasParameterAnnotations || i > argTypes.length) { - return null; - } - return paramAnnotations[i]; - } - /** - * Goes through the attributes on the method and identifies any that are - * RuntimeParameterAnnotations, extracting their contents and storing them - * as parameter annotations. There are two kinds of parameter annotation - - * visible and invisible. Once they have been unpacked, these attributes are - * deleted. (The annotations will be rebuilt as attributes when someone - * builds a Method object out of this MethodGen object). + * Call notify() method on all observers. This method is not called automatically whenever the state has changed, but + * has to be called by the user after they have finished editing the object. */ - private void ensureExistingParameterAnnotationsUnpacked() - { - if (haveUnpackedParameterAnnotations) { - return; - } - // Find attributes that contain parameter annotation data - final Attribute[] attrs = getAttributes(); - ParameterAnnotations paramAnnVisAttr = null; - ParameterAnnotations paramAnnInvisAttr = null; - for (final Attribute attribute : attrs) { - if (attribute instanceof ParameterAnnotations) - { - // Initialize paramAnnotations - if (!hasParameterAnnotations) - { - @SuppressWarnings({"rawtypes", "unchecked"}) // OK - final List[] parmList = new List[argTypes.length]; - paramAnnotations = parmList; - for (int j = 0; j < argTypes.length; j++) { - paramAnnotations[j] = new ArrayList<>(); - } - } - hasParameterAnnotations = true; - final ParameterAnnotations rpa = (ParameterAnnotations) attribute; - if (rpa instanceof RuntimeVisibleParameterAnnotations) { - paramAnnVisAttr = rpa; - } else { - paramAnnInvisAttr = rpa; - } - final ParameterAnnotationEntry[] parameterAnnotationEntries = rpa.getParameterAnnotationEntries(); - for (int j = 0; j < parameterAnnotationEntries.length; j++) - { - // This returns Annotation[] ... - final ParameterAnnotationEntry immutableArray = rpa.getParameterAnnotationEntries()[j]; - // ... which needs transforming into an AnnotationGen[] ... - final List mutable = makeMutableVersion(immutableArray.getAnnotationEntries()); - // ... then add these to any we already know about - paramAnnotations[j].addAll(mutable); - } + public void update() { + if (observers != null) { + for (final MethodObserver observer : observers) { + observer.notify(this); } } - if (paramAnnVisAttr != null) { - removeAttribute(paramAnnVisAttr); - } - if (paramAnnInvisAttr != null) { - removeAttribute(paramAnnInvisAttr); - } - haveUnpackedParameterAnnotations = true; - } - - private List makeMutableVersion(final AnnotationEntry[] mutableArray) - { - final List result = new ArrayList<>(); - for (final AnnotationEntry element : mutableArray) { - result.add(new AnnotationEntryGen(element, getConstantPool(), - false)); - } - return result; } - public void addParameterAnnotation(final int parameterIndex, - final AnnotationEntryGen annotation) - { - ensureExistingParameterAnnotationsUnpacked(); - if (!hasParameterAnnotations) - { - @SuppressWarnings({"rawtypes", "unchecked"}) - final List[] parmList = new List[argTypes.length]; - paramAnnotations = parmList; - hasParameterAnnotations = true; - } - final List existingAnnotations = paramAnnotations[parameterIndex]; - if (existingAnnotations != null) - { - existingAnnotations.add(annotation); - } - else - { - final List l = new ArrayList<>(); - l.add(annotation); - paramAnnotations[parameterIndex] = l; + private void updateLocalVariableTable(final LocalVariableTable a) { + removeLocalVariables(); + for (final LocalVariable l : a.getLocalVariableTable()) { + InstructionHandle start = il.findHandle(l.getStartPC()); + final InstructionHandle end = il.findHandle(l.getStartPC() + l.getLength()); + // Repair malformed handles + if (null == start) { + start = il.getStart(); + } + // end == null => live to end of method + // Since we are recreating the LocalVaraible, we must + // propagate the orig_index to new copy. + addLocalVariable(l.getName(), Type.getType(l.getSignature()), l.getIndex(), start, end, l.getOrigIndex()); } } - - /** - * @return Comparison strategy object - */ - public static BCELComparator getComparator() { - return bcelComparator; - } - - - /** - * @param comparator Comparison strategy object - */ - public static void setComparator( final BCELComparator comparator ) { - bcelComparator = comparator; - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default two MethodGen objects are said to be equal when - * their names and signatures are equal. - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals( final Object obj ) { - return bcelComparator.equals(this, obj); - } - - - /** - * Return value as defined by given BCELComparator strategy. - * By default return the hashcode of the method's name XOR signature. - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return bcelComparator.hashCode(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MethodObserver.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,11 +22,10 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Implement this interface if you're interested in changes to a MethodGen object - * and register yourself with addObserver(). - * + * Implement this interface if you're interested in changes to a MethodGen object and register yourself with + * addObserver(). */ public interface MethodObserver { - void notify( MethodGen method ); + void notify(MethodGen method); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITORENTER.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,8 +24,10 @@ /** * MONITORENTER - Enter monitor for object - *
    Stack: ..., objectref -> ...
    * + *
    + * Stack: ..., objectref -> ...
    + * 
    * @LastModified: Jan 2020 */ public class MONITORENTER extends Instruction implements ExceptionThrower, StackConsumer { @@ -34,27 +36,21 @@ super(com.sun.org.apache.bcel.internal.Const.MONITORENTER, (short) 1); } - - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.NULL_POINTER_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitStackConsumer(this); v.visitMONITORENTER(this); } + + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.NULL_POINTER_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MONITOREXIT.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,8 +24,10 @@ /** * MONITOREXIT - Exit monitor for object - *
    Stack: ..., objectref -> ...
    * + *
    + * Stack: ..., objectref -> ...
    + * 
    * @LastModified: Jan 2020 */ public class MONITOREXIT extends Instruction implements ExceptionThrower, StackConsumer { @@ -34,27 +36,21 @@ super(com.sun.org.apache.bcel.internal.Const.MONITOREXIT, (short) 1); } - - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.NULL_POINTER_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitStackConsumer(this); v.visitMONITOREXIT(this); } + + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.NULL_POINTER_EXCEPTION}; + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/MULTIANEWARRAY.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,23 +30,21 @@ /** * MULTIANEWARRAY - Create new mutidimensional array of references - *
    Stack: ..., count1, [count2, ...] -> ..., arrayref
    * + *
    + * Stack: ..., count1, [count2, ...] -> ..., arrayref
    + * 
    */ -public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, - ExceptionThrower { +public class MULTIANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, ExceptionThrower { private short dimensions; - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ MULTIANEWARRAY() { } - public MULTIANEWARRAY(final int index, final short dimensions) { super(com.sun.org.apache.bcel.internal.Const.MULTIANEWARRAY, index); if (dimensions < 1) { @@ -56,100 +54,89 @@ super.setLength(4); } - /** - * Dump instruction as byte code to stream out. - * @param out Output stream + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object */ @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - out.writeShort(super.getIndex()); - out.writeByte(dimensions); + public void accept(final Visitor v) { + v.visitLoadClass(this); + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitTypedInstruction(this); + v.visitCPInstruction(this); + v.visitMULTIANEWARRAY(this); } - /** - * Read needed data (i.e., no. dimension) from file. + * Also works for instructions whose stack effect depends on the constant pool entry they reference. + * + * @return Number of words consumed from stack by this instruction */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - super.initFromFile(bytes, wide); - dimensions = bytes.readByte(); - super.setLength(4); - } - - - /** - * @return number of dimensions to be created - */ - public final short getDimensions() { + public int consumeStack(final ConstantPoolGen cpg) { return dimensions; } - - /** - * @return mnemonic for instruction - */ - @Override - public String toString( final boolean verbose ) { - return super.toString(verbose) + " " + super.getIndex() + " " + dimensions; - } - - /** - * @return mnemonic for instruction with symbolic references resolved + * Dump instruction as byte code to stream out. + * + * @param out Output stream */ @Override - public String toString( final ConstantPool cp ) { - return super.toString(cp) + " " + dimensions; + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + out.writeShort(super.getIndex()); + out.writeByte(dimensions); } - /** - * Also works for instructions whose stack effect depends on the - * constant pool entry they reference. - * @return Number of words consumed from stack by this instruction + * @return number of dimensions to be created */ - @Override - public int consumeStack( final ConstantPoolGen cpg ) { + public final short getDimensions() { return dimensions; } - @Override public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, - ExceptionConst.ILLEGAL_ACCESS_ERROR, + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, ExceptionConst.ILLEGAL_ACCESS_ERROR, ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION); } - @Override - public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { + public ObjectType getLoadClassType(final ConstantPoolGen cpg) { Type t = getType(cpg); if (t instanceof ArrayType) { t = ((ArrayType) t).getBasicType(); } - return (t instanceof ObjectType) ? (ObjectType) t : null; + return t instanceof ObjectType ? (ObjectType) t : null; } + /** + * Read needed data (i.e., no. dimension) from file. + */ + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.initFromFile(bytes, wide); + dimensions = bytes.readByte(); + super.setLength(4); + } /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object + * @return mnemonic for instruction */ @Override - public void accept( final Visitor v ) { - v.visitLoadClass(this); - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitTypedInstruction(this); - v.visitCPInstruction(this); - v.visitMULTIANEWARRAY(this); + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + super.getIndex() + " " + dimensions; + } + + /** + * @return mnemonic for instruction with symbolic references resolved + */ + @Override + public String toString(final ConstantPool cp) { + return super.toString(cp) + " " + dimensions; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NamedAndTyped.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,20 +22,15 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denote entity that has both name and type. This is true for local variables, - * methods and fields. - * + * Denote entity that has both name and type. This is true for local variables, methods and fields. */ public interface NamedAndTyped { String getName(); - Type getType(); + void setName(String name); - void setName( String name ); - - - void setType( Type type ); + void setType(Type type); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NameSignatureInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,27 +27,36 @@ import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8; /** - * Super class for FieldOrMethod and INVOKEDYNAMIC, since they both have - * names and signatures + * Super class for FieldOrMethod and INVOKEDYNAMIC, since they both have names and signatures * * @since 6.0 */ public abstract class NameSignatureInstruction extends CPInstruction { public NameSignatureInstruction() { - super(); } public NameSignatureInstruction(final short opcode, final int index) { super(opcode, index); } + /** + * @return name of referenced method/field. + */ + public String getName(final ConstantPoolGen cpg) { + final ConstantPool cp = cpg.getConstantPool(); + final ConstantNameAndType cnat = getNameAndType(cpg); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + public ConstantNameAndType getNameAndType(final ConstantPoolGen cpg) { final ConstantPool cp = cpg.getConstantPool(); final ConstantCP cmr = (ConstantCP) cp.getConstant(super.getIndex()); - return (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); } - /** @return signature of referenced method/field. + + /** + * @return signature of referenced method/field. */ public String getSignature(final ConstantPoolGen cpg) { final ConstantPool cp = cpg.getConstantPool(); @@ -55,12 +64,4 @@ return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); } - /** @return name of referenced method/field. - */ - public String getName(final ConstantPoolGen cpg) { - final ConstantPool cp = cpg.getConstantPool(); - final ConstantNameAndType cnat = getNameAndType(cpg); - return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); - } - } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEWARRAY.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,56 +27,64 @@ import com.sun.org.apache.bcel.internal.util.ByteSequence; /** - * NEWARRAY - Create new array of basic type (int, short, ...) - *
    Stack: ..., count -> ..., arrayref
    - * type must be one of T_INT, T_SHORT, ... + * NEWARRAY - Create new array of basic type (int, short, ...) + * + *
    + * Stack: ..., count -> ..., arrayref
    + * 
    * + * type must be one of T_INT, T_SHORT, ... * @LastModified: Jan 2020 */ -public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower, - StackProducer { +public class NEWARRAY extends Instruction implements AllocationInstruction, ExceptionThrower, StackProducer { private byte type; - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ NEWARRAY() { } + public NEWARRAY(final BasicType type) { + this(type.getType()); + } public NEWARRAY(final byte type) { super(com.sun.org.apache.bcel.internal.Const.NEWARRAY, (short) 2); this.type = type; } - - public NEWARRAY(final BasicType type) { - this(type.getType()); + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitAllocationInstruction(this); + v.visitExceptionThrower(this); + v.visitStackProducer(this); + v.visitNEWARRAY(this); } - /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { out.writeByte(super.getOpcode()); out.writeByte(type); } - - /** - * @return numeric code for basic element type - */ - public final byte getTypecode() { - return type; + @Override + public Class[] getExceptions() { + return new Class[] {ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION}; } - /** * @return type of constructed array */ @@ -84,47 +92,27 @@ return new ArrayType(BasicType.getType(type), 1); } - /** - * @return mnemonic for instruction + * @return numeric code for basic element type */ - @Override - public String toString( final boolean verbose ) { - return super.toString(verbose) + " " + com.sun.org.apache.bcel.internal.Const.getTypeName(type); + public final byte getTypecode() { + return type; } - /** * Read needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { type = bytes.readByte(); super.setLength(2); } - - @Override - public Class[] getExceptions() { - return new Class[] { - ExceptionConst.NEGATIVE_ARRAY_SIZE_EXCEPTION - }; - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object + * @return mnemonic for instruction */ @Override - public void accept( final Visitor v ) { - v.visitAllocationInstruction(this); - v.visitExceptionThrower(this); - v.visitStackProducer(this); - v.visitNEWARRAY(this); + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + com.sun.org.apache.bcel.internal.Const.getTypeName(type); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NEW.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,49 +25,31 @@ /** * NEW - Create new object - *
    Stack: ... -> ..., objectref
    * + *
    + * Stack: ... -> ..., objectref
    + * 
    */ -public class NEW extends CPInstruction implements LoadClass, AllocationInstruction, - ExceptionThrower, StackProducer { +public class NEW extends CPInstruction implements LoadClass, AllocationInstruction, ExceptionThrower, StackProducer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ NEW() { } - public NEW(final int index) { super(com.sun.org.apache.bcel.internal.Const.NEW, index); } - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, - ExceptionConst.ILLEGAL_ACCESS_ERROR, - ExceptionConst.INSTANTIATION_ERROR); - } - - - @Override - public ObjectType getLoadClassType( final ConstantPoolGen cpg ) { - return (ObjectType) getType(cpg); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitLoadClass(this); v.visitAllocationInstruction(this); v.visitExceptionThrower(this); @@ -76,4 +58,15 @@ v.visitCPInstruction(this); v.visitNEW(this); } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_CLASS_AND_INTERFACE_RESOLUTION, ExceptionConst.ILLEGAL_ACCESS_ERROR, + ExceptionConst.INSTANTIATION_ERROR); + } + + @Override + public ObjectType getLoadClassType(final ConstantPoolGen cpg) { + return (ObjectType) getType(cpg); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/NOP.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,7 +23,6 @@ /** * NOP - Do nothing - * */ public class NOP extends Instruction { @@ -31,17 +30,14 @@ super(com.sun.org.apache.bcel.internal.Const.NOP, (short) 1); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitNOP(this); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ObjectType.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,62 +24,78 @@ import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Denotes reference such as java.lang.String. - * */ public class ObjectType extends ReferenceType { - private final String className; // Class name of type - /** + * Constructs a new instance. + * + * @param className fully qualified class name, e.g. java.lang.String + * @return a new instance. * @since 6.0 */ public static ObjectType getInstance(final String className) { return new ObjectType(className); } + private final String className; // Class name of type + /** + * Constructs a new instance. + * * @param className fully qualified class name, e.g. java.lang.String */ public ObjectType(final String className) { - super(Const.T_REFERENCE, "L" + className.replace('.', '/') + ";"); - this.className = className.replace('/', '.'); + super(Const.T_REFERENCE, "L" + Utility.packageToPath(className) + ";"); + this.className = Utility.pathToPackage(className); } - - /** @return name of referenced class + /** + * Java Virtual Machine Specification edition 2, 5.4.4 Access Control + * + * @throws ClassNotFoundException if the class referenced by this type can't be found */ - public String getClassName() { - return className; + public boolean accessibleTo(final ObjectType accessor) throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(className); + if (jc.isPublic()) { + return true; + } + final JavaClass acc = Repository.lookupClass(accessor.className); + return acc.getPackageName().equals(jc.getPackageName()); } - - /** @return a hash code value for the object. + /** + * @return true if both type objects refer to the same class. */ @Override - public int hashCode() { - return className.hashCode(); + public boolean equals(final Object type) { + return type instanceof ObjectType && ((ObjectType) type).className.equals(className); } - - /** @return true if both type objects refer to the same class. + /** + * @return name of referenced class */ @Override - public boolean equals( final Object type ) { - return (type instanceof ObjectType) - ? ((ObjectType) type).className.equals(className) - : false; + public String getClassName() { + return className; } + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + return className.hashCode(); + } /** - * If "this" doesn't reference a class, it references an interface - * or a non-existant entity. - * @deprecated (since 6.0) this method returns an inaccurate result - * if the class or interface referenced cannot - * be found: use referencesClassExact() instead + * If "this" doesn't reference a class, it references an interface or a non-existant entity. + * @deprecated (since 6.0) this method returns an inaccurate result if the class or interface referenced cannot be + * found: use referencesClassExact() instead */ @Deprecated public boolean referencesClass() { @@ -91,13 +107,22 @@ } } + /** + * Return true if this type references a class, false if it references an interface. + * + * @return true if the type references a class, false if it references an interface + * @throws ClassNotFoundException if the class or interface referenced by this type can't be found + */ + public boolean referencesClassExact() throws ClassNotFoundException { + final JavaClass jc = Repository.lookupClass(className); + return jc.isClass(); + } /** - * If "this" doesn't reference an interface, it references a class - * or a non-existant entity. - * @deprecated (since 6.0) this method returns an inaccurate result - * if the class or interface referenced cannot - * be found: use referencesInterfaceExact() instead + * If "this" doesn't reference an interface, it references a class or a non-existant entity. + * + * @deprecated (since 6.0) this method returns an inaccurate result if the class or interface referenced cannot be + * found: use referencesInterfaceExact() instead */ @Deprecated public boolean referencesInterface() { @@ -109,59 +134,26 @@ } } - /** - * Return true if this type references a class, - * false if it references an interface. - * @return true if the type references a class, false if - * it references an interface - * @throws ClassNotFoundException if the class or interface - * referenced by this type can't be found - */ - public boolean referencesClassExact() throws ClassNotFoundException { - final JavaClass jc = Repository.lookupClass(className); - return jc.isClass(); - } - - - /** - * Return true if this type references an interface, - * false if it references a class. - * @return true if the type references an interface, false if - * it references a class - * @throws ClassNotFoundException if the class or interface - * referenced by this type can't be found + * Return true if this type references an interface, false if it references a class. + * + * @return true if the type references an interface, false if it references a class + * @throws ClassNotFoundException if the class or interface referenced by this type can't be found */ public boolean referencesInterfaceExact() throws ClassNotFoundException { final JavaClass jc = Repository.lookupClass(className); return !jc.isClass(); } - /** * Return true if this type is a subclass of given ObjectType. - * @throws ClassNotFoundException if any of this class's superclasses - * can't be found + * + * @throws ClassNotFoundException if any of this class's superclasses can't be found */ - public boolean subclassOf( final ObjectType superclass ) throws ClassNotFoundException { + public boolean subclassOf(final ObjectType superclass) throws ClassNotFoundException { if (this.referencesInterfaceExact() || superclass.referencesInterfaceExact()) { return false; } return Repository.instanceOf(this.className, superclass.className); } - - - /** - * Java Virtual Machine Specification edition 2, 5.4.4 Access Control - * @throws ClassNotFoundException if the class referenced by this type - * can't be found - */ - public boolean accessibleTo( final ObjectType accessor ) throws ClassNotFoundException { - final JavaClass jc = Repository.lookupClass(className); - if (jc.isPublic()) { - return true; - } - final JavaClass acc = Repository.lookupClass(accessor.className); - return acc.getPackageName().equals(jc.getPackageName()); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP2.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,8 +24,9 @@ /** * POP2 - Pop two top operand stack words * - *
    Stack: ..., word2, word1 -> ...
    - * + *
    + * Stack: ..., word2, word1 -> ...
    + * 
    */ public class POP2 extends StackInstruction implements PopInstruction { @@ -33,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.POP2); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitPopInstruction(this); v.visitStackInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PopInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,8 +22,7 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denotes an unparameterized instruction to pop a value on top from the stack, - * such as ISTORE, POP, PUTSTATIC. + * Denotes an unparameterized instruction to pop a value on top from the stack, such as ISTORE, POP, PUTSTATIC. * * @see ISTORE * @see POP diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/POP.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,8 +24,9 @@ /** * POP - Pop top operand stack word * - *
    Stack: ..., word -> ...
    - * + *
    + * Stack: ..., word -> ...
    + * 
    */ public class POP extends StackInstruction implements PopInstruction { @@ -33,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.POP); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitPopInstruction(this); v.visitStackInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PushInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,10 +22,10 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denotes an unparameterized instruction to produce a value on top of the stack, - * such as ILOAD, LDC, SIPUSH, DUP, ICONST, etc. + * Denotes an unparameterized instruction to produce a value on top of the stack, such as ILOAD, LDC, SIPUSH, DUP, + * ICONST, etc. + * * - * @see ILOAD * @see ICONST * @see LDC diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUSH.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,79 +20,61 @@ package com.sun.org.apache.bcel.internal.generic; +import java.util.Objects; + import com.sun.org.apache.bcel.internal.Const; /** - * Wrapper class for push operations, which are implemented either as BIPUSH, - * LDC or xCONST_n instructions. - * - * @LastModified: Jan 2020 + * Wrapper class for push operations, which are implemented either as BIPUSH, LDC or xCONST_n instructions. + * @LastModified: Feb 2023 */ public final class PUSH implements CompoundInstruction, VariableLengthInstruction { - private Instruction instruction; - + private final Instruction instruction; /** - * This constructor also applies for values of type short, char, byte + * Pushes an array type constant, for example {@code int[].class}, {@code String[].class}, and so on. * - * @param cp Constant pool - * @param value to be pushed + * @param cp generated constant pool. + * @param value to be pushed. + * @since 6.7.0 */ - public PUSH(final ConstantPoolGen cp, final int value) { - if ((value >= -1) && (value <= 5)) { - instruction = InstructionConst.getInstruction(Const.ICONST_0 + value); - } else if (Instruction.isValidByte(value)) { - instruction = new BIPUSH((byte) value); - } else if (Instruction.isValidShort(value)) { - instruction = new SIPUSH((short) value); + public PUSH(final ConstantPoolGen cp, final ArrayType value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; } else { - instruction = new LDC(cp.addInteger(value)); + instruction = new LDC(cp.addArrayClass(value)); } } - - /** + /** * @param cp Constant pool * @param value to be pushed */ public PUSH(final ConstantPoolGen cp, final boolean value) { + Objects.requireNonNull(cp, "cp"); instruction = InstructionConst.getInstruction(Const.ICONST_0 + (value ? 1 : 0)); } - /** * @param cp Constant pool * @param value to be pushed */ - public PUSH(final ConstantPoolGen cp, final float value) { - if (value == 0.0) { - instruction = InstructionConst.FCONST_0; - } else if (value == 1.0) { - instruction = InstructionConst.FCONST_1; - } else if (value == 2.0) { - instruction = InstructionConst.FCONST_2; - } else { - instruction = new LDC(cp.addFloat(value)); - } + public PUSH(final ConstantPoolGen cp, final Boolean value) { + this(cp, value.booleanValue()); } - /** + * creates a push object from a Character value. Warning: Make sure not to attempt to allow autoboxing to create this + * value parameter, as an alternative constructor will be called + * * @param cp Constant pool * @param value to be pushed */ - public PUSH(final ConstantPoolGen cp, final long value) { - if (value == 0) { - instruction = InstructionConst.LCONST_0; - } else if (value == 1) { - instruction = InstructionConst.LCONST_1; - } else { - instruction = new LDC2_W(cp.addLong(value)); - } + public PUSH(final ConstantPoolGen cp, final Character value) { + this(cp, value.charValue()); } - /** * @param cp Constant pool * @param value to be pushed @@ -107,30 +89,51 @@ } } - /** * @param cp Constant pool * @param value to be pushed */ - public PUSH(final ConstantPoolGen cp, final String value) { - if (value == null) { - instruction = InstructionConst.ACONST_NULL; + public PUSH(final ConstantPoolGen cp, final float value) { + if (value == 0.0) { + instruction = InstructionConst.FCONST_0; + } else if (value == 1.0) { + instruction = InstructionConst.FCONST_1; + } else if (value == 2.0) { + instruction = InstructionConst.FCONST_2; } else { - instruction = new LDC(cp.addString(value)); + instruction = new LDC(cp.addFloat(value)); } } /** + * This constructor also applies for values of type short, char, byte * - * @param cp - * @param value - * @since 6.0 + * @param cp Constant pool + * @param value to be pushed */ - public PUSH(final ConstantPoolGen cp, final ObjectType value) { - if (value == null) { - instruction = InstructionConst.ACONST_NULL; + public PUSH(final ConstantPoolGen cp, final int value) { + if (value >= -1 && value <= 5) { + instruction = InstructionConst.getInstruction(Const.ICONST_0 + value); + } else if (Instruction.isValidByte(value)) { + instruction = new BIPUSH((byte) value); + } else if (Instruction.isValidShort(value)) { + instruction = new SIPUSH((short) value); } else { - instruction = new LDC(cp.addClass(value)); + instruction = new LDC(cp.addInteger(value)); + } + } + + /** + * @param cp Constant pool + * @param value to be pushed + */ + public PUSH(final ConstantPoolGen cp, final long value) { + if (value == 0) { + instruction = InstructionConst.LCONST_0; + } else if (value == 1) { + instruction = InstructionConst.LCONST_1; + } else { + instruction = new LDC2_W(cp.addLong(value)); } } @@ -139,7 +142,7 @@ * @param value to be pushed */ public PUSH(final ConstantPoolGen cp, final Number value) { - if ((value instanceof Integer) || (value instanceof Short) || (value instanceof Byte)) { + if (value instanceof Integer || value instanceof Short || value instanceof Byte) { instruction = new PUSH(cp, value.intValue()).instruction; } else if (value instanceof Double) { instruction = new PUSH(cp, value.doubleValue()).instruction; @@ -152,39 +155,41 @@ } } - /** - * creates a push object from a Character value. Warning: Make sure not to attempt to allow - * autoboxing to create this value parameter, as an alternative constructor will be called * - * @param cp Constant pool - * @param value to be pushed + * @param cp + * @param value + * @since 6.0 */ - public PUSH(final ConstantPoolGen cp, final Character value) { - this(cp, value.charValue()); + public PUSH(final ConstantPoolGen cp, final ObjectType value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; + } else { + instruction = new LDC(cp.addClass(value)); + } } - /** * @param cp Constant pool * @param value to be pushed */ - public PUSH(final ConstantPoolGen cp, final Boolean value) { - this(cp, value.booleanValue()); + public PUSH(final ConstantPoolGen cp, final String value) { + if (value == null) { + instruction = InstructionConst.ACONST_NULL; + } else { + instruction = new LDC(cp.addString(value)); + } } + public Instruction getInstruction() { + return instruction; + } @Override public InstructionList getInstructionList() { return new InstructionList(instruction); } - - public Instruction getInstruction() { - return instruction; - } - - /** * @return mnemonic for instruction */ diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTFIELD.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,50 +26,37 @@ /** * PUTFIELD - Put field in object - *
    Stack: ..., objectref, value -> ...
    + * + *
    + * Stack: ..., objectref, value -> ...
    + * 
    + * * OR - *
    Stack: ..., objectref, value.word1, value.word2 -> ...
    * + *
    + * Stack: ..., objectref, value.word1, value.word2 -> ...
    + * 
    */ public class PUTFIELD extends FieldInstruction implements PopInstruction, ExceptionThrower { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ PUTFIELD() { } - public PUTFIELD(final int index) { super(Const.PUTFIELD, index); } - - @Override - public int consumeStack( final ConstantPoolGen cpg ) { - return getFieldSize(cpg) + 1; - } - - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.NULL_POINTER_EXCEPTION, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitStackConsumer(this); v.visitPopInstruction(this); @@ -80,4 +67,15 @@ v.visitFieldInstruction(this); v.visitPUTFIELD(this); } + + @Override + public int consumeStack(final ConstantPoolGen cpg) { + return getFieldSize(cpg) + 1; + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.NULL_POINTER_EXCEPTION, + ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/PUTSTATIC.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,49 +26,37 @@ /** * PUTSTATIC - Put static field in class - *
    Stack: ..., value -> ...
    + * + *
    + * Stack: ..., value -> ...
    + * 
    + * * OR - *
    Stack: ..., value.word1, value.word2 -> ...
    * + *
    + * Stack: ..., value.word1, value.word2 -> ...
    + * 
    */ public class PUTSTATIC extends FieldInstruction implements ExceptionThrower, PopInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ PUTSTATIC() { } - public PUTSTATIC(final int index) { super(Const.PUTSTATIC, index); } - - @Override - public int consumeStack( final ConstantPoolGen cpg ) { - return getFieldSize(cpg); - } - - - @Override - public Class[] getExceptions() { - return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, - ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); - } - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitStackConsumer(this); v.visitPopInstruction(this); @@ -79,4 +67,14 @@ v.visitFieldInstruction(this); v.visitPUTSTATIC(this); } + + @Override + public int consumeStack(final ConstantPoolGen cpg) { + return getFieldSize(cpg); + } + + @Override + public Class[] getExceptions() { + return ExceptionConst.createExceptions(ExceptionConst.EXCS.EXCS_FIELD_AND_METHOD_RESOLUTION, ExceptionConst.INCOMPATIBLE_CLASS_CHANGE_ERROR); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReferenceType.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,133 +26,204 @@ /** * Super class for object and array types. - * */ public abstract class ReferenceType extends Type { + /** + * Class is non-abstract but not instantiable from the outside + */ + ReferenceType() { + super(Const.T_OBJECT, ""); + } + protected ReferenceType(final byte t, final String s) { super(t, s); } - - /** Class is non-abstract but not instantiable from the outside + /** + * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an + * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t + * is returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If + * "this" or t is an ArrayType, then Type.OBJECT is returned. If "this" or t is a ReferenceType referencing an + * interface, then Type.OBJECT is returned. If not all of the two classes' superclasses cannot be found, "null" is + * returned. See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + * + * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has slightly changed semantics. + * @throws ClassNotFoundException on failure to find superclasses of this type, or the type passed as a parameter */ - ReferenceType() { - super(Const.T_OBJECT, ""); + @Deprecated + public ReferenceType firstCommonSuperclass(final ReferenceType t) throws ClassNotFoundException { + if (this.equals(Type.NULL)) { + return t; + } + if (t.equals(Type.NULL) || this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also + * say all the objects referenced by Type.NULL were derived from java.lang.Object. However, the Java Language's + * "instanceof" operator proves us wrong: "null" is not referring to an instance of java.lang.Object :) + */ + } + if (this instanceof ArrayType || t instanceof ArrayType) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + } + return getFirstCommonSuperclassInternal(t); } - /** - * Return true iff this type is castable to another type t as defined in - * the JVM specification. The case where this is Type.NULL is not - * defined (see the CHECKCAST definition in the JVM specification). - * However, because e.g. CHECKCAST doesn't throw a - * ClassCastException when casting a null reference to any Object, - * true is returned in this case. + * This commutative operation returns the first common superclass (narrowest ReferenceType referencing a class, not an + * interface). If one of the types is a superclass of the other, the former is returned. If "this" is Type.NULL, then t + * is returned. If t is Type.NULL, then "this" is returned. If "this" equals t ['this.equals(t)'] "this" is returned. If + * "this" or t is an ArrayType, then Type.OBJECT is returned; unless their dimensions match. Then an ArrayType of the + * same number of dimensions is returned, with its basic type being the first common super class of the basic types of + * "this" and t. If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. If not all of + * the two classes' superclasses cannot be found, "null" is returned. See the JVM specification edition 2, "4.9.2 The + * Bytecode Verifier". * - * @throws ClassNotFoundException if any classes or interfaces required - * to determine assignment compatibility can't be found + * @throws ClassNotFoundException on failure to find superclasses of this type, or the type passed as a parameter */ - public boolean isCastableTo( final Type t ) throws ClassNotFoundException { + public ReferenceType getFirstCommonSuperclass(final ReferenceType t) throws ClassNotFoundException { if (this.equals(Type.NULL)) { - return t instanceof ReferenceType; // If this is ever changed in isAssignmentCompatible() + return t; } - return isAssignmentCompatibleWith(t); - /* Yes, it's true: It's the same definition. - * See vmspec2 AASTORE / CHECKCAST definitions. - */ + if (t.equals(Type.NULL) || this.equals(t)) { + return this; + /* + * TODO: Above sounds a little arbitrary. On the other hand, there is no object referenced by Type.NULL so we can also + * say all the objects referenced by Type.NULL were derived from java.lang.Object. However, the Java Language's + * "instanceof" operator proves us wrong: "null" is not referring to an instance of java.lang.Object :) + */ + } + /* This code is from a bug report by Konstantin Shagin */ + if (this instanceof ArrayType && t instanceof ArrayType) { + final ArrayType arrType1 = (ArrayType) this; + final ArrayType arrType2 = (ArrayType) t; + if (arrType1.getDimensions() == arrType2.getDimensions() && arrType1.getBasicType() instanceof ObjectType + && arrType2.getBasicType() instanceof ObjectType) { + return new ArrayType(((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), + arrType1.getDimensions()); + } + } + if (this instanceof ArrayType || t instanceof ArrayType) { + return Type.OBJECT; + // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? + } + return getFirstCommonSuperclassInternal(t); } + private ReferenceType getFirstCommonSuperclassInternal(final ReferenceType t) throws ClassNotFoundException { + if (this instanceof ObjectType && ((ObjectType) this).referencesInterfaceExact() + || t instanceof ObjectType && ((ObjectType) t).referencesInterfaceExact()) { + return Type.OBJECT; + // TODO: The above line is correct comparing to the vmspec2. But one could + // make class file verification a bit stronger here by using the notion of + // superinterfaces or even castability or assignment compatibility. + } + // this and t are ObjectTypes, see above. + final ObjectType thiz = (ObjectType) this; + final ObjectType other = (ObjectType) t; + final JavaClass[] thizSups = Repository.getSuperClasses(thiz.getClassName()); + final JavaClass[] otherSups = Repository.getSuperClasses(other.getClassName()); + if (thizSups == null || otherSups == null) { + return null; + } + // Waaahh... + final JavaClass[] thisSups = new JavaClass[thizSups.length + 1]; + final JavaClass[] tSups = new JavaClass[otherSups.length + 1]; + System.arraycopy(thizSups, 0, thisSups, 1, thizSups.length); + System.arraycopy(otherSups, 0, tSups, 1, otherSups.length); + thisSups[0] = Repository.lookupClass(thiz.getClassName()); + tSups[0] = Repository.lookupClass(other.getClassName()); + for (final JavaClass tSup : tSups) { + for (final JavaClass thisSup : thisSups) { + if (thisSup.equals(tSup)) { + return ObjectType.getInstance(thisSup.getClassName()); + } + } + } + // Huh? Did you ask for Type.OBJECT's superclass?? + return null; + } /** - * Return true iff this is assignment compatible with another type t - * as defined in the JVM specification; see the AASTORE definition - * there. - * @throws ClassNotFoundException if any classes or interfaces required - * to determine assignment compatibility can't be found + * Return true iff this is assignment compatible with another type t as defined in the JVM specification; see the + * AASTORE definition there. + * + * @throws ClassNotFoundException if any classes or interfaces required to determine assignment compatibility can't be + * found */ - public boolean isAssignmentCompatibleWith( final Type t ) throws ClassNotFoundException { + public boolean isAssignmentCompatibleWith(final Type t) throws ClassNotFoundException { if (!(t instanceof ReferenceType)) { return false; } final ReferenceType T = (ReferenceType) t; if (this.equals(Type.NULL)) { - return true; // This is not explicitely stated, but clear. Isn't it? + return true; // This is not explicitly stated, but clear. Isn't it? } - /* If this is a class type then + /* + * If this is a class type then */ - if ((this instanceof ObjectType) && (((ObjectType) this).referencesClassExact())) { - /* If T is a class type, then this must be the same class as T, - or this must be a subclass of T; + if (this instanceof ObjectType && ((ObjectType) this).referencesClassExact()) { + /* + * If T is a class type, then this must be the same class as T, or this must be a subclass of T; */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { - if (this.equals(T)) { - return true; - } - if (Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T) - .getClassName())) { - return true; - } + if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() + && (this.equals(T) || Repository.instanceOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName()))) { + return true; } - /* If T is an interface type, this must implement interface T. + /* + * If T is an interface type, this must implement interface T. */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { - if (Repository.implementationOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) { - return true; - } + if (T instanceof ObjectType && ((ObjectType) T).referencesInterfaceExact() + && Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName())) { + return true; } } - /* If this is an interface type, then: + /* + * If this is an interface type, then: */ - if ((this instanceof ObjectType) && (((ObjectType) this).referencesInterfaceExact())) { - /* If T is a class type, then T must be Object (2.4.7). + if (this instanceof ObjectType && ((ObjectType) this).referencesInterfaceExact()) { + /* + * If T is a class type, then T must be Object (2.4.7). */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { - if (T.equals(Type.OBJECT)) { - return true; - } + if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() && T.equals(Type.OBJECT)) { + return true; } - /* If T is an interface type, then T must be the same interface - * as this or a superinterface of this (2.13.2). + /* + * If T is an interface type, then T must be the same interface as this or a superinterface of this (2.13.2). */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { - if (this.equals(T)) { - return true; - } - if (Repository.implementationOf(((ObjectType) this).getClassName(), - ((ObjectType) T).getClassName())) { - return true; - } + if (T instanceof ObjectType && ((ObjectType) T).referencesInterfaceExact() + && (this.equals(T) || Repository.implementationOf(((ObjectType) this).getClassName(), ((ObjectType) T).getClassName()))) { + return true; } } - /* If this is an array type, namely, the type SC[], that is, an - * array of components of type SC, then: + /* + * If this is an array type, namely, the type SC[], that is, an array of components of type SC, then: */ if (this instanceof ArrayType) { - /* If T is a class type, then T must be Object (2.4.7). + /* + * If T is a class type, then T must be Object (2.4.7). */ - if ((T instanceof ObjectType) && (((ObjectType) T).referencesClassExact())) { - if (T.equals(Type.OBJECT)) { - return true; - } + if (T instanceof ObjectType && ((ObjectType) T).referencesClassExact() && T.equals(Type.OBJECT)) { + return true; } - /* If T is an array type TC[], that is, an array of components - * of type TC, then one of the following must be true: + /* + * If T is an array type TC[], that is, an array of components of type TC, then one of the following must be true: */ if (T instanceof ArrayType) { - /* TC and SC are the same primitive type (2.4.1). + /* + * TC and SC are the same primitive type (2.4.1). */ final Type sc = ((ArrayType) this).getElementType(); final Type tc = ((ArrayType) T).getElementType(); if (sc instanceof BasicType && tc instanceof BasicType && sc.equals(tc)) { return true; } - /* TC and SC are reference types (2.4.6), and type SC is - * assignable to TC by these runtime rules. + /* + * TC and SC are reference types (2.4.6), and type SC is assignable to TC by these runtime rules. */ - if (tc instanceof ReferenceType && sc instanceof ReferenceType - && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { + if (tc instanceof ReferenceType && sc instanceof ReferenceType && ((ReferenceType) sc).isAssignmentCompatibleWith(tc)) { return true; } } @@ -162,7 +233,7 @@ // are at least two different pages where assignment compatibility is defined and // on one of them "interfaces implemented by arrays" is exchanged with "'Cloneable' or // 'java.io.Serializable'" - if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterfaceExact())) { + if (T instanceof ObjectType && ((ObjectType) T).referencesInterfaceExact()) { for (final String element : Const.getInterfacesImplementedByArrays()) { if (T.equals(ObjectType.getInstance(element))) { return true; @@ -173,160 +244,21 @@ return false; // default. } - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned; - * unless their dimensions match. Then an ArrayType of the same - * number of dimensions is returned, with its basic type being the - * first common super class of the basic types of "this" and t. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". + * Return true iff this type is castable to another type t as defined in the JVM specification. The case where this is + * Type.NULL is not defined (see the CHECKCAST definition in the JVM specification). However, because e.g. CHECKCAST + * doesn't throw a ClassCastException when casting a null reference to any Object, true is returned in this case. * - * @throws ClassNotFoundException on failure to find superclasses of this - * type, or the type passed as a parameter + * @throws ClassNotFoundException if any classes or interfaces required to determine assignment compatibility can't be + * found */ - public ReferenceType getFirstCommonSuperclass( final ReferenceType t ) throws ClassNotFoundException { + public boolean isCastableTo(final Type t) throws ClassNotFoundException { if (this.equals(Type.NULL)) { - return t; - } - if (t.equals(Type.NULL)) { - return this; - } - if (this.equals(t)) { - return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is - * no object referenced by Type.NULL so we can also say all the objects - * referenced by Type.NULL were derived from java.lang.Object. - * However, the Java Language's "instanceof" operator proves us wrong: - * "null" is not referring to an instance of java.lang.Object :) - */ - } - /* This code is from a bug report by Konstantin Shagin */ - if ((this instanceof ArrayType) && (t instanceof ArrayType)) { - final ArrayType arrType1 = (ArrayType) this; - final ArrayType arrType2 = (ArrayType) t; - if ((arrType1.getDimensions() == arrType2.getDimensions()) - && arrType1.getBasicType() instanceof ObjectType - && arrType2.getBasicType() instanceof ObjectType) { - return new ArrayType(((ObjectType) arrType1.getBasicType()) - .getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()), arrType1 - .getDimensions()); - } - } - if ((this instanceof ArrayType) || (t instanceof ArrayType)) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - } - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterfaceExact()) - || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterfaceExact())) { - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - } - // this and t are ObjectTypes, see above. - final ObjectType thiz = (ObjectType) this; - final ObjectType other = (ObjectType) t; - final JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - final JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - if ((thiz_sups == null) || (other_sups == null)) { - return null; - } - // Waaahh... - final JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - final JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - for (final JavaClass t_sup : t_sups) { - for (final JavaClass this_sup : this_sups) { - if (this_sup.equals(t_sup)) { - return ObjectType.getInstance(this_sup.getClassName()); - } - } - } - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; - } - - /** - * This commutative operation returns the first common superclass (narrowest ReferenceType - * referencing a class, not an interface). - * If one of the types is a superclass of the other, the former is returned. - * If "this" is Type.NULL, then t is returned. - * If t is Type.NULL, then "this" is returned. - * If "this" equals t ['this.equals(t)'] "this" is returned. - * If "this" or t is an ArrayType, then Type.OBJECT is returned. - * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned. - * If not all of the two classes' superclasses cannot be found, "null" is returned. - * See the JVM specification edition 2, "4.9.2 The Bytecode Verifier". - * - * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has - * slightly changed semantics. - * @throws ClassNotFoundException on failure to find superclasses of this - * type, or the type passed as a parameter - */ - @Deprecated - public ReferenceType firstCommonSuperclass( final ReferenceType t ) throws ClassNotFoundException { - if (this.equals(Type.NULL)) { - return t; - } - if (t.equals(Type.NULL)) { - return this; - } - if (this.equals(t)) { - return this; - /* - * TODO: Above sounds a little arbitrary. On the other hand, there is - * no object referenced by Type.NULL so we can also say all the objects - * referenced by Type.NULL were derived from java.lang.Object. - * However, the Java Language's "instanceof" operator proves us wrong: - * "null" is not referring to an instance of java.lang.Object :) - */ - } - if ((this instanceof ArrayType) || (t instanceof ArrayType)) { - return Type.OBJECT; - // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType? - } - if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) - || ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface())) { - return Type.OBJECT; - // TODO: The above line is correct comparing to the vmspec2. But one could - // make class file verification a bit stronger here by using the notion of - // superinterfaces or even castability or assignment compatibility. - } - // this and t are ObjectTypes, see above. - final ObjectType thiz = (ObjectType) this; - final ObjectType other = (ObjectType) t; - final JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName()); - final JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName()); - if ((thiz_sups == null) || (other_sups == null)) { - return null; - } - // Waaahh... - final JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1]; - final JavaClass[] t_sups = new JavaClass[other_sups.length + 1]; - System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length); - System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length); - this_sups[0] = Repository.lookupClass(thiz.getClassName()); - t_sups[0] = Repository.lookupClass(other.getClassName()); - for (final JavaClass t_sup : t_sups) { - for (final JavaClass this_sup : this_sups) { - if (this_sup.equals(t_sup)) { - return ObjectType.getInstance(this_sup.getClassName()); - } - } + return t instanceof ReferenceType; // If this is ever changed in isAssignmentCompatible() } - // Huh? Did you ask for Type.OBJECT's superclass?? - return null; + return isAssignmentCompatibleWith(t); + /* + * Yes, it's true: It's the same definition. See vmspec2 AASTORE / CHECKCAST definitions. + */ } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RET.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,35 +29,44 @@ /** * RET - Return from subroutine * - *
    Stack: ... -> ...
    - * + *
    + * Stack: ... -> ...
    + * 
    */ public class RET extends Instruction implements IndexedInstruction, TypedInstruction { private boolean wide; private int index; // index to local variable containg the return address - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ RET() { } - public RET(final int index) { super(com.sun.org.apache.bcel.internal.Const.RET, (short) 2); setIndex(index); // May set wide as side effect } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitRET(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { if (wide) { out.writeByte(com.sun.org.apache.bcel.internal.Const.WIDE); } @@ -69,22 +78,27 @@ } } - - private void setWide() { - wide = index > com.sun.org.apache.bcel.internal.Const.MAX_BYTE; - if (wide) { - super.setLength(4); // Including the wide byte - } else { - super.setLength(2); - } + /** + * @return index of local variable containg the return address + */ + @Override + public final int getIndex() { + return index; } + /** + * @return return address type + */ + @Override + public Type getType(final ConstantPoolGen cp) { + return ReturnaddressType.NO_TARGET; + } /** * Read needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { this.wide = wide; if (wide) { index = bytes.readUnsignedShort(); @@ -95,21 +109,11 @@ } } - - /** - * @return index of local variable containg the return address - */ - @Override - public final int getIndex() { - return index; - } - - /** * Set index of local variable containg the return address */ @Override - public final void setIndex( final int n ) { + public final void setIndex(final int n) { if (n < 0) { throw new ClassGenException("Negative index value: " + n); } @@ -117,34 +121,20 @@ setWide(); } + private void setWide() { + wide = index > com.sun.org.apache.bcel.internal.Const.MAX_BYTE; + if (wide) { + super.setLength(4); // Including the wide byte + } else { + super.setLength(2); + } + } /** * @return mnemonic for instruction */ @Override - public String toString( final boolean verbose ) { + public String toString(final boolean verbose) { return super.toString(verbose) + " " + index; } - - - /** @return return address type - */ - @Override - public Type getType( final ConstantPoolGen cp ) { - return ReturnaddressType.NO_TARGET; - } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitRET(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java 2023-10-06 05:33:33.000000000 +0000 @@ -33,7 +33,6 @@ public static final ReturnaddressType NO_TARGET = new ReturnaddressType(); private InstructionHandle returnTarget; - /** * A Returnaddress [that doesn't know where to return to]. */ @@ -41,7 +40,6 @@ super(Const.T_ADDRESS, ""); } - /** * Creates a ReturnaddressType object with a target. */ @@ -50,23 +48,11 @@ this.returnTarget = returnTarget; } - - /** @return a hash code value for the object. - */ - @Override - public int hashCode() { - if (returnTarget == null) { - return 0; - } - return returnTarget.hashCode(); - } - - /** * Returns if the two Returnaddresses refer to the same target. */ @Override - public boolean equals( final Object rat ) { + public boolean equals(final Object rat) { if (!(rat instanceof ReturnaddressType)) { return false; } @@ -77,11 +63,21 @@ return that.returnTarget.equals(this.returnTarget); } - /** * @return the target of this ReturnaddressType */ public InstructionHandle getTarget() { return returnTarget; } + + /** + * @return a hash code value for the object. + */ + @Override + public int hashCode() { + if (returnTarget == null) { + return 0; + } + return returnTarget.hashCode(); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/ReturnInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -26,19 +26,16 @@ /** * Super class for the xRETURN family of instructions. * - * @LastModified: Jan 2020 + * @LastModified: Feb 2023 */ -public abstract class ReturnInstruction extends Instruction implements ExceptionThrower, - TypedInstruction, StackConsumer { +public abstract class ReturnInstruction extends Instruction implements ExceptionThrower, TypedInstruction, StackConsumer { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ ReturnInstruction() { } - /** * @param opcode of instruction */ @@ -46,40 +43,36 @@ super(opcode, (short) 1); } - - public Type getType() { - final short _opcode = super.getOpcode(); - switch (_opcode) { - case Const.IRETURN: - return Type.INT; - case Const.LRETURN: - return Type.LONG; - case Const.FRETURN: - return Type.FLOAT; - case Const.DRETURN: - return Type.DOUBLE; - case Const.ARETURN: - return Type.OBJECT; - case Const.RETURN: - return Type.VOID; - default: // Never reached - throw new ClassGenException("Unknown type " + _opcode); - } - } - - @Override public Class[] getExceptions() { - return new Class[] { - ExceptionConst.ILLEGAL_MONITOR_STATE - }; + return new Class[] {ExceptionConst.ILLEGAL_MONITOR_STATE}; } + public Type getType() { + final short opcode = super.getOpcode(); + switch (opcode) { + case Const.IRETURN: + return Type.INT; + case Const.LRETURN: + return Type.LONG; + case Const.FRETURN: + return Type.FLOAT; + case Const.DRETURN: + return Type.DOUBLE; + case Const.ARETURN: + return Type.OBJECT; + case Const.RETURN: + return Type.VOID; + default: // Never reached + throw new ClassGenException("Unknown type " + opcode); + } + } - /** @return type associated with the instruction + /** + * @return type associated with the instruction */ @Override - public Type getType( final ConstantPoolGen cp ) { + public Type getType(final ConstantPoolGen cp) { return getType(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/RETURN.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,9 +22,11 @@ package com.sun.org.apache.bcel.internal.generic; /** - * RETURN - Return from void method - *
    Stack: ... -> <empty>
    + * RETURN - Return from void method * + *
    + * Stack: ... -> <empty>
    + * 
    */ public class RETURN extends ReturnInstruction { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.RETURN); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitExceptionThrower(this); v.visitTypedInstruction(this); v.visitStackConsumer(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SALOAD.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * SALOAD - Load short from array - *
    Stack: ..., arrayref, index -> ..., value
    * + *
    + * Stack: ..., arrayref, index -> ..., value
    + * 
    */ public class SALOAD extends ArrayInstruction implements StackProducer { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.SALOAD); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackProducer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SASTORE.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * SASTORE - Store into short array - *
    Stack: ..., arrayref, index, value -> ...
    * + *
    + * Stack: ..., arrayref, index, value -> ...
    + * 
    */ public class SASTORE extends ArrayInstruction implements StackConsumer { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.SASTORE); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitExceptionThrower(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Select.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,34 +27,60 @@ /** * Select - Abstract super class for LOOKUPSWITCH and TABLESWITCH instructions. * - *

    We use our super's {@code target} property as the default target. + *

    + * We use our super's {@code target} property as the default target. * * @see LOOKUPSWITCH * @see TABLESWITCH * @see InstructionList * @LastModified: May 2021 */ -public abstract class Select extends BranchInstruction implements VariableLengthInstruction, - StackConsumer /* @since 6.0 */, StackProducer { +public abstract class Select extends BranchInstruction implements VariableLengthInstruction, StackConsumer /* @since 6.0 */, StackProducer { - private int[] match; // matches, i.e., case 1: ... TODO could be package-protected? - private int[] indices; // target offsets TODO could be package-protected? - private InstructionHandle[] targets; // target objects in instruction list TODO could be package-protected? - private int fixed_length; // fixed length defined by subclasses TODO could be package-protected? - private int match_length; // number of cases TODO could be package-protected? - private int padding = 0; // number of pad bytes for alignment TODO could be package-protected? + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int[] match; // matches, i.e., case 1: ... TODO could be package-protected? + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int[] indices; // target offsets TODO could be package-protected? + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected InstructionHandle[] targets; // target objects in instruction list TODO could be package-protected? /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int fixed_length; // fixed length defined by subclasses TODO could be package-protected? + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int match_length; // number of cases TODO could be package-protected? + + /** + * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter + */ + @Deprecated + protected int padding; // number of pad bytes for alignment TODO could be package-protected? + + /** + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ Select() { } - /** - * (Match, target) pairs for switch. - * `Match' and `targets' must have the same length of course. + * (Match, target) pairs for switch. 'Match' and 'targets' must have the same length of course. * * @param match array of matching values * @param targets instruction targets @@ -71,126 +97,25 @@ notifyTarget(null, target2, this); } if ((match_length = match.length) != targets.length) { - throw new ClassGenException("Match and target array have not the same length: Match length: " + - match.length + " Target length: " + targets.length); + throw new ClassGenException("Match and target array have not the same length: Match length: " + match.length + " Target length: " + targets.length); } indices = new int[match_length]; } - - /** - * Since this is a variable length instruction, it may shift the following - * instructions which then need to update their position. - * - * Called by InstructionList.setPositions when setting the position for every - * instruction. In the presence of variable length instructions `setPositions' - * performs multiple passes over the instruction list to calculate the - * correct (byte) positions and offsets by calling this function. - * - * @param offset additional offset caused by preceding (variable length) instructions - * @param max_offset the maximum offset that may be caused by these instructions - * @return additional offset caused by possible change of this instruction's length - */ - @Override - protected int updatePosition( final int offset, final int max_offset ) { - setPosition(getPosition() + offset); // Additional offset caused by preceding SWITCHs, GOTOs, etc. - final short old_length = (short) super.getLength(); - /* Alignment on 4-byte-boundary, + 1, because of tag byte. - */ - padding = (4 - ((getPosition() + 1) % 4)) % 4; - super.setLength((short) (fixed_length + padding)); // Update length - return super.getLength() - old_length; - } - - - /** - * Dump instruction as byte code to stream out. - * @param out Output stream - */ - @Override - public void dump( final DataOutputStream out ) throws IOException { - out.writeByte(super.getOpcode()); - for (int i = 0; i < padding; i++) { - out.writeByte(0); - } - super.setIndex(getTargetOffset()); // Write default target offset - out.writeInt(super.getIndex()); - } - - - /** - * Read needed data (e.g. index) from file. - */ - @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes - for (int i = 0; i < padding; i++) { - bytes.readByte(); - } - // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) - super.setIndex(bytes.readInt()); - } - - - /** - * @return mnemonic for instruction - */ - @Override - public String toString( final boolean verbose ) { - final StringBuilder buf = new StringBuilder(super.toString(verbose)); - if (verbose) { - for (int i = 0; i < match_length; i++) { - String s = "null"; - if (targets[i] != null) { - s = targets[i].getInstruction().toString(); - } - buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append( - indices[i]).append("})"); - } - } else { - buf.append(" ..."); - } - return buf.toString(); - } - - - /** - * Set branch target for `i'th case - */ - public void setTarget( final int i, final InstructionHandle target ) { // TODO could be package-protected? - notifyTarget(targets[i], target, this); - targets[i] = target; - } - - - /** - * @param old_ih old target - * @param new_ih new target - */ @Override - public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { - boolean targeted = false; - if (super.getTarget() == old_ih) { - targeted = true; - setTarget(new_ih); - } - for (int i = 0; i < targets.length; i++) { - if (targets[i] == old_ih) { - targeted = true; - setTarget(i, new_ih); - } - } - if (!targeted) { - throw new ClassGenException("Not targeting " + old_ih); - } + protected Object clone() throws CloneNotSupportedException { + final Select copy = (Select) super.clone(); + copy.match = match.clone(); + copy.indices = indices.clone(); + copy.targets = targets.clone(); + return copy; } - /** * @return true, if ih is target of this instruction */ @Override - public boolean containsTarget( final InstructionHandle ih ) { + public boolean containsTarget(final InstructionHandle ih) { if (super.getTarget() == ih) { return true; } @@ -202,17 +127,6 @@ return false; } - - @Override - protected Object clone() throws CloneNotSupportedException { - final Select copy = (Select) super.clone(); - copy.match = match.clone(); - copy.indices = indices.clone(); - copy.targets = targets.clone(); - return copy; - } - - /** * Inform targets that they're not targeted anymore. */ @@ -224,14 +138,28 @@ } } - /** - * @return array of match indices + * Dump instruction as byte code to stream out. + * + * @param out Output stream */ - public int[] getMatchs() { - return match; + @Override + public void dump(final DataOutputStream out) throws IOException { + out.writeByte(super.getOpcode()); + for (int i = 0; i < padding; i++) { + out.writeByte(0); + } + super.setIndex(getTargetOffset()); // Write default target offset + out.writeInt(super.getIndex()); } + /** + * @return the fixed_length + * @since 6.0 + */ + final int getFixedLength() { + return fixed_length; + } /** * @return array of match target offsets @@ -240,12 +168,12 @@ return indices; } - /** - * @return array of match targets + * @return index entry from indices + * @since 6.0 */ - public InstructionHandle[] getTargets() { - return targets; + final int getIndices(final int index) { + return indices[index]; } /** @@ -256,13 +184,28 @@ return match[index]; } + /** + * @return the match_length + * @since 6.0 + */ + final int getMatchLength() { + return match_length; + } /** - * @return index entry from indices + * @return array of match indices + */ + public int[] getMatchs() { + return match; + } + + /** + * + * @return the padding * @since 6.0 */ - final int getIndices(final int index) { - return indices[index]; + final int getPadding() { + return padding; } /** @@ -273,41 +216,47 @@ return targets[index]; } - /** - * @return the fixed_length - * @since 6.0 + * @return array of match targets */ - final int getFixed_length() { - return fixed_length; + public InstructionHandle[] getTargets() { + return targets; } - /** - * @param fixed_length the fixed_length to set - * @since 6.0 + * Read needed data (e.g. index) from file. */ - final void setFixed_length(final int fixed_length) { - this.fixed_length = fixed_length; + @Override + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + padding = (4 - bytes.getIndex() % 4) % 4; // Compute number of pad bytes + for (int i = 0; i < padding; i++) { + bytes.readByte(); + } + // Default branch target common for both cases (TABLESWITCH, LOOKUPSWITCH) + super.setIndex(bytes.readInt()); } - /** - * @return the match_length + * @param fixedLength the fixed_length to set * @since 6.0 */ - final int getMatch_length() { - return match_length; + final void setFixedLength(final int fixedLength) { + this.fixed_length = fixedLength; } + /** @since 6.0 */ + final int setIndices(final int i, final int value) { + indices[i] = value; + return value; // Allow use in nested calls + } /** - * @param match_length the match_length to set + * + * @param array * @since 6.0 */ - final int setMatch_length(final int match_length) { - this.match_length = match_length; - return match_length; + final void setIndices(final int[] array) { + indices = array; } /** @@ -325,17 +274,25 @@ * @param array * @since 6.0 */ - final void setIndices(final int[] array) { - indices = array; + final void setMatches(final int[] array) { + match = array; } /** - * - * @param array + * @param matchLength the match_length to set * @since 6.0 */ - final void setMatches(final int[] array) { - match = array; + final int setMatchLength(final int matchLength) { + this.match_length = matchLength; + return matchLength; + } + + /** + * Set branch target for 'i'th case + */ + public void setTarget(final int i, final InstructionHandle target) { // TODO could be package-protected? + notifyTarget(targets[i], target, this); + targets[i] = target; } /** @@ -348,18 +305,68 @@ } /** - * - * @return the padding - * @since 6.0 + * @return mnemonic for instruction */ - final int getPadding() { - return padding; + @Override + public String toString(final boolean verbose) { + final StringBuilder buf = new StringBuilder(super.toString(verbose)); + if (verbose) { + for (int i = 0; i < match_length; i++) { + String s = "null"; + if (targets[i] != null) { + s = targets[i].getInstruction().toString(); + } + buf.append("(").append(match[i]).append(", ").append(s).append(" = {").append(indices[i]).append("})"); + } + } else { + buf.append(" ..."); + } + return buf.toString(); } + /** + * Since this is a variable length instruction, it may shift the following instructions which then need to update their + * position. + * + * Called by InstructionList.setPositions when setting the position for every instruction. In the presence of variable + * length instructions 'setPositions' performs multiple passes over the instruction list to calculate the correct (byte) + * positions and offsets by calling this function. + * + * @param offset additional offset caused by preceding (variable length) instructions + * @param maxOffset the maximum offset that may be caused by these instructions + * @return additional offset caused by possible change of this instruction's length + */ + @Override + protected int updatePosition(final int offset, final int maxOffset) { + setPosition(getPosition() + offset); // Additional offset caused by preceding SWITCHs, GOTOs, etc. + final short oldLength = (short) super.getLength(); + /* + * Alignment on 4-byte-boundary, + 1, because of tag byte. + */ + padding = (4 - (getPosition() + 1) % 4) % 4; + super.setLength((short) (fixed_length + padding)); // Update length + return super.getLength() - oldLength; + } - /** @since 6.0 */ - final int setIndices(final int i, final int value) { - indices[i] = value; - return value; // Allow use in nested calls + /** + * @param oldIh old target + * @param newIh new target + */ + @Override + public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) { + boolean targeted = false; + if (super.getTarget() == oldIh) { + targeted = true; + setTarget(newIh); + } + for (int i = 0; i < targets.length; i++) { + if (targets[i] == oldIh) { + targeted = true; + setTarget(i, newIh); + } + } + if (!targeted) { + throw new ClassGenException("Not targeting " + oldIh); + } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SimpleElementValueGen.java 2023-10-06 05:33:33.000000000 +0000 @@ -35,102 +35,84 @@ /** * @since 6.0 */ -public class SimpleElementValueGen extends ElementValueGen -{ +public class SimpleElementValueGen extends ElementValueGen { // For primitive types and string type, this points to the value entry in // the cpGen // For 'class' this points to the class entry in the cpGen - private int idx; + private final int idx; - // ctors for each supported type... type could be inferred but for now lets - // force it to be passed - /** - * Protected ctor used for deserialization, doesn't *put* an entry in the - * constant pool, assumes the one at the supplied index is correct. - */ - protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) { super(type, cpGen); - this.idx = idx; + if (value) { + idx = getConstantPool().addInteger(1); + } else { + idx = getConstantPool().addInteger(0); + } } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) { super(type, cpGen); idx = getConstantPool().addInteger(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) { super(type, cpGen); - idx = getConstantPool().addLong(value); + idx = getConstantPool().addInteger(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) { super(type, cpGen); idx = getConstantPool().addDouble(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) { super(type, cpGen); idx = getConstantPool().addFloat(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) { super(type, cpGen); idx = getConstantPool().addInteger(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) { super(type, cpGen); - idx = getConstantPool().addInteger(value); + idx = getConstantPool().addLong(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) { super(type, cpGen); idx = getConstantPool().addInteger(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) - { + public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) { super(type, cpGen); - if (value) { - idx = getConstantPool().addInteger(1); - } else { - idx = getConstantPool().addInteger(0); - } + idx = getConstantPool().addUtf8(value); } - public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) - { + // ctors for each supported type... type could be inferred but for now lets + // force it to be passed + /** + * Protected ctor used for deserialization, doesn't *put* an entry in the constant pool, assumes the one at the supplied + * index is correct. + */ + protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) { super(type, cpGen); - idx = getConstantPool().addUtf8(value); + this.idx = idx; } /** - * The boolean controls whether we copy info from the 'old' constant pool to - * the 'new'. You need to use this ctor if the annotation is being copied - * from one file to another. + * The boolean controls whether we copy info from the 'old' constant pool to the 'new'. You need to use this ctor if the + * annotation is being copied from one file to another. */ - public SimpleElementValueGen(final SimpleElementValue value, - final ConstantPoolGen cpool, final boolean copyPoolEntries) - { + public SimpleElementValueGen(final SimpleElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) { super(value.getElementValueType(), cpool); - if (!copyPoolEntries) - { + if (!copyPoolEntries) { // J5ASSERT: Could assert value.stringifyValue() is the same as // cpool.getConstant(SimpleElementValuevalue.getIndex()) idx = value.getIndex(); - } - else - { - switch (value.getElementValueType()) - { + } else { + switch (value.getElementValueType()) { case STRING: idx = cpool.addUtf8(value.getValueString()); break; @@ -153,12 +135,9 @@ idx = cpool.addDouble(value.getValueDouble()); break; case PRIMITIVE_BOOLEAN: - if (value.getValueBoolean()) - { + if (value.getValueBoolean()) { idx = cpool.addInteger(1); - } - else - { + } else { idx = cpool.addInteger(0); } break; @@ -166,52 +145,63 @@ idx = cpool.addInteger(value.getValueShort()); break; default: - throw new IllegalArgumentException( - "SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType()); + throw new IllegalArgumentException("SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType()); } } } + @Override + public void dump(final DataOutputStream dos) throws IOException { + dos.writeByte(super.getElementValueType()); // u1 kind of value + switch (super.getElementValueType()) { + case PRIMITIVE_INT: + case PRIMITIVE_BYTE: + case PRIMITIVE_CHAR: + case PRIMITIVE_FLOAT: + case PRIMITIVE_LONG: + case PRIMITIVE_BOOLEAN: + case PRIMITIVE_SHORT: + case PRIMITIVE_DOUBLE: + case STRING: + dos.writeShort(idx); + break; + default: + throw new IllegalStateException("SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType()); + } + } + /** * Return immutable variant */ @Override - public ElementValue getElementValue() - { + public ElementValue getElementValue() { return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool()); } - public int getIndex() - { + public int getIndex() { return idx; } - public String getValueString() - { - if (super.getElementValueType() != STRING) { - throw new IllegalStateException( - "Dont call getValueString() on a non STRING ElementValue"); + public int getValueInt() { + if (super.getElementValueType() != PRIMITIVE_INT) { + throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue"); } - final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); + final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); return c.getBytes(); } - public int getValueInt() - { - if (super.getElementValueType() != PRIMITIVE_INT) { - throw new IllegalStateException( - "Dont call getValueString() on a non STRING ElementValue"); + public String getValueString() { + if (super.getElementValueType() != STRING) { + throw new IllegalStateException("Dont call getValueString() on a non STRING ElementValue"); } - final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); + final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx); return c.getBytes(); } // Whatever kind of value it is, return it as a string @Override - public String stringifyValue() - { - switch (super.getElementValueType()) - { + public String stringifyValue() { + switch (super.getElementValueType()) { case PRIMITIVE_INT: final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx); return Integer.toString(c.getBytes()); @@ -243,31 +233,7 @@ final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx); return cu8.getBytes(); default: - throw new IllegalStateException( - "SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); - } - } - - @Override - public void dump(final DataOutputStream dos) throws IOException - { - dos.writeByte(super.getElementValueType()); // u1 kind of value - switch (super.getElementValueType()) - { - case PRIMITIVE_INT: - case PRIMITIVE_BYTE: - case PRIMITIVE_CHAR: - case PRIMITIVE_FLOAT: - case PRIMITIVE_LONG: - case PRIMITIVE_BOOLEAN: - case PRIMITIVE_SHORT: - case PRIMITIVE_DOUBLE: - case STRING: - dos.writeShort(idx); - break; - default: - throw new IllegalStateException( - "SimpleElementValueGen doesnt know how to write out type " + super.getElementValueType()); + throw new IllegalStateException("SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType()); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SIPUSH.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,85 +28,76 @@ /** * SIPUSH - Push short * - *

    Stack: ... -> ..., value
    - * + *
    + * Stack: ... -> ..., value
    + * 
    */ public class SIPUSH extends Instruction implements ConstantPushInstruction { private short b; - /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ SIPUSH() { } - public SIPUSH(final short b) { super(com.sun.org.apache.bcel.internal.Const.SIPUSH, (short) 3); this.b = b; } - /** - * Dump instruction as short code to stream out. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object */ @Override - public void dump( final DataOutputStream out ) throws IOException { - super.dump(out); - out.writeShort(b); + public void accept(final Visitor v) { + v.visitPushInstruction(this); + v.visitStackProducer(this); + v.visitTypedInstruction(this); + v.visitConstantPushInstruction(this); + v.visitSIPUSH(this); } - /** - * @return mnemonic for instruction + * Dump instruction as short code to stream out. */ @Override - public String toString( final boolean verbose ) { - return super.toString(verbose) + " " + b; + public void dump(final DataOutputStream out) throws IOException { + super.dump(out); + out.writeShort(b); } - /** - * Read needed data (e.g. index) from file. + * @return Type.SHORT */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { - super.setLength(3); - b = bytes.readShort(); + public Type getType(final ConstantPoolGen cp) { + return Type.SHORT; } - @Override public Number getValue() { return Integer.valueOf(b); } - - /** @return Type.SHORT + /** + * Read needed data (e.g. index) from file. */ @Override - public Type getType( final ConstantPoolGen cp ) { - return Type.SHORT; + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { + super.setLength(3); + b = bytes.readShort(); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object + * @return mnemonic for instruction */ @Override - public void accept( final Visitor v ) { - v.visitPushInstruction(this); - v.visitStackProducer(this); - v.visitTypedInstruction(this); - v.visitConstantPushInstruction(this); - v.visitSIPUSH(this); + public String toString(final boolean verbose) { + return super.toString(verbose) + " " + b; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackConsumer.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,11 +23,11 @@ /** * Denote an instruction that may consume a value from the stack. - * */ public interface StackConsumer { - /** @return how many words are consumed from stack + /** + * @return how many words are consumed from stack */ - int consumeStack( ConstantPoolGen cpg ); + int consumeStack(ConstantPoolGen cpg); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,18 +23,15 @@ /** * Super class for stack operations like DUP and POP. - * */ public abstract class StackInstruction extends Instruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ StackInstruction() { } - /** * @param opcode instruction opcode */ @@ -42,10 +39,10 @@ super(opcode, (short) 1); } - - /** @return Type.UNKNOWN + /** + * @return Type.UNKNOWN */ - public Type getType( final ConstantPoolGen cp ) { + public Type getType(final ConstantPoolGen cp) { return Type.UNKNOWN; } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StackProducer.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,13 +22,12 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denote an instruction that may produce a value on top of the stack - * (this excludes DUP_X1, e.g.) - * + * Denotes an instruction that may produce a value on top of the stack (this excludes DUP_X1, e.g.) */ public interface StackProducer { - /** @return how many words are produced on stack + /** + * @return how many words are produced on stack */ - int produceStack( ConstantPoolGen cpg ); + int produceStack(ConstantPoolGen cpg); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/StoreInstruction.java 2023-10-06 05:33:33.000000000 +0000 @@ -22,42 +22,35 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Denotes an unparameterized instruction to store a value into a local variable, - * e.g. ISTORE. - * + * Denotes an unparameterized instruction to store a value into a local variable, e.g. ISTORE. */ public abstract class StoreInstruction extends LocalVariableInstruction implements PopInstruction { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. - * tag and length are defined in readInstruction and initFromFile, respectively. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. tag and length are defined in + * readInstruction and initFromFile, respectively. */ - StoreInstruction(final short canon_tag, final short c_tag) { - super(canon_tag, c_tag); + StoreInstruction(final short canonTag, final short cTag) { + super(canonTag, cTag); } - /** * @param opcode Instruction opcode - * @param c_tag Instruction number for compact version, ASTORE_0, e.g. + * @param cTag Instruction number for compact version, ASTORE_0, e.g. * @param n local variable index (unsigned short) */ - protected StoreInstruction(final short opcode, final short c_tag, final int n) { - super(opcode, c_tag, n); + protected StoreInstruction(final short opcode, final short cTag, final int n) { + super(opcode, cTag, n); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitPopInstruction(this); v.visitTypedInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWAP.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,8 +23,10 @@ /** * SWAP - Swa top operand stack word - *
    Stack: ..., word2, word1 -> ..., word1, word2
    * + *
    + * Stack: ..., word2, word1 -> ..., word1, word2
    + * 
    */ public class SWAP extends StackInstruction implements StackConsumer, StackProducer { @@ -32,17 +34,14 @@ super(com.sun.org.apache.bcel.internal.Const.SWAP); } - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. * * @param v Visitor object */ @Override - public void accept( final Visitor v ) { + public void accept(final Visitor v) { v.visitStackConsumer(this); v.visitStackProducer(this); v.visitStackInstruction(this); diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/SWITCH.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,91 +21,34 @@ package com.sun.org.apache.bcel.internal.generic; +import java.util.Arrays; + /** - * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or - * TABLESWITCH instruction, depending on whether the match values (int[]) can be - * sorted with no gaps between the numbers. - * + * SWITCH - Branch depending on int value, generates either LOOKUPSWITCH or TABLESWITCH instruction, depending on + * whether the match values (int[]) can be sorted with no gaps between the numbers. */ public final class SWITCH implements CompoundInstruction { - private int[] match; - private InstructionHandle[] targets; - private Select instruction; - private int matchLength; - - /** - * Template for switch() constructs. If the match array can be - * sorted in ascending order with gaps no larger than max_gap - * between the numbers, a TABLESWITCH instruction is generated, and - * a LOOKUPSWITCH otherwise. The former may be more efficient, but - * needs more space. - * - * Note, that the key array always will be sorted, though we leave - * the original arrays unaltered. - * - * @param match array of match values (case 2: ... case 7: ..., etc.) - * @param targets the instructions to be branched to for each case - * @param target the default target - * @param max_gap maximum gap that may between case branches + * @return match is sorted in ascending order with no gap bigger than maxGap? */ - public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target, final int max_gap) { - this.match = match.clone(); - this.targets = targets.clone(); - if ((matchLength = match.length) < 2) { - instruction = new TABLESWITCH(match, targets, target); - } else { - sort(0, matchLength - 1); - if (matchIsOrdered(max_gap)) { - fillup(max_gap, target); - instruction = new TABLESWITCH(this.match, this.targets, target); - } else { - instruction = new LOOKUPSWITCH(this.match, this.targets, target); - } - } - } - - - public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target) { - this(match, targets, target, 1); - } - - - private void fillup( final int max_gap, final InstructionHandle target ) { - final int max_size = matchLength + matchLength * max_gap; - final int[] m_vec = new int[max_size]; - final InstructionHandle[] t_vec = new InstructionHandle[max_size]; - int count = 1; - m_vec[0] = match[0]; - t_vec[0] = targets[0]; + private static boolean matchIsOrdered(final int[] match, final int matchLength, final int maxGap) { for (int i = 1; i < matchLength; i++) { - final int prev = match[i - 1]; - final int gap = match[i] - prev; - for (int j = 1; j < gap; j++) { - m_vec[count] = prev + j; - t_vec[count] = target; - count++; + if (match[i] - match[i - 1] > maxGap) { + return false; } - m_vec[count] = match[i]; - t_vec[count] = targets[i]; - count++; } - match = new int[count]; - targets = new InstructionHandle[count]; - System.arraycopy(m_vec, 0, match, 0, count); - System.arraycopy(t_vec, 0, targets, 0, count); + return true; } - /** - * Sort match and targets array with QuickSort. + * Sorts match and targets array with QuickSort. */ - private void sort( final int l, final int r ) { + private static void sort(final int l, final int r, final int[] match, final InstructionHandle[] targets) { int i = l; int j = r; int h; - final int m = match[(l + r) >>> 1]; + final int m = match[l + r >>> 1]; InstructionHandle h2; do { while (match[i] < m) { @@ -126,34 +69,71 @@ } } while (i <= j); if (l < j) { - sort(l, j); + sort(l, j, match, targets); } if (i < r) { - sort(i, r); + sort(i, r, match, targets); } } + private final Select instruction; + + public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target) { + this(match, targets, target, 1); + } /** - * @return match is sorted in ascending order with no gap bigger than max_gap? + * Template for switch() constructs. If the match array can be sorted in ascending order with gaps no larger than + * maxGap between the numbers, a TABLESWITCH instruction is generated, and a LOOKUPSWITCH otherwise. The former may be + * more efficient, but needs more space. + * + * Note, that the key array always will be sorted, though we leave the original arrays unaltered. + * + * @param match array of match values (case 2: ... case 7: ..., etc.) + * @param targets the instructions to be branched to for each case + * @param target the default target + * @param maxGap maximum gap that may between case branches */ - private boolean matchIsOrdered( final int max_gap ) { - for (int i = 1; i < matchLength; i++) { - if (match[i] - match[i - 1] > max_gap) { - return false; + public SWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle target, final int maxGap) { + int[] matchClone = match.clone(); + final InstructionHandle[] targetsClone = targets.clone(); + final int matchLength = match.length; + if (matchLength < 2) { + instruction = new TABLESWITCH(match, targets, target); + } else { + sort(0, matchLength - 1, matchClone, targetsClone); + if (matchIsOrdered(matchClone, matchLength, maxGap)) { + final int maxSize = matchLength + matchLength * maxGap; + final int[] mVec = new int[maxSize]; + final InstructionHandle[] tVec = new InstructionHandle[maxSize]; + int count = 1; + mVec[0] = match[0]; + tVec[0] = targets[0]; + for (int i = 1; i < matchLength; i++) { + final int prev = match[i - 1]; + final int gap = match[i] - prev; + for (int j = 1; j < gap; j++) { + mVec[count] = prev + j; + tVec[count] = target; + count++; + } + mVec[count] = match[i]; + tVec[count] = targets[i]; + count++; + } + instruction = new TABLESWITCH(Arrays.copyOf(mVec, count), Arrays.copyOf(tVec, count), target); + } else { + instruction = new LOOKUPSWITCH(matchClone, targetsClone, target); } } - return true; } + public Instruction getInstruction() { + return instruction; + } @Override public InstructionList getInstructionList() { return new InstructionList(instruction); } - - - public Instruction getInstruction() { - return instruction; - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TABLESWITCH.java 2023-10-06 05:33:33.000000000 +0000 @@ -34,83 +34,76 @@ public class TABLESWITCH extends Select { /** - * Empty constructor needed for Instruction.readInstruction. - * Not to be used otherwise. + * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise. */ TABLESWITCH() { } - /** - * @param match sorted array of match values, match[0] must be low value, - * match[match_length - 1] high value + * @param match sorted array of match values, match[0] must be low value, match[match_length - 1] high value * @param targets where to branch for matched values * @param defaultTarget default branch */ public TABLESWITCH(final int[] match, final InstructionHandle[] targets, final InstructionHandle defaultTarget) { super(com.sun.org.apache.bcel.internal.Const.TABLESWITCH, match, targets, defaultTarget); /* Alignment remainder assumed 0 here, until dump time */ - final short _length = (short) (13 + getMatch_length() * 4); - super.setLength(_length); - setFixed_length(_length); + final short length = (short) (13 + getMatchLength() * 4); + super.setLength(length); + setFixedLength(length); } + /** + * Call corresponding visitor method(s). The order is: Call visitor methods of implemented interfaces first, then call + * methods according to the class hierarchy in descending order, i.e., the most specific visitXXX() call comes last. + * + * @param v Visitor object + */ + @Override + public void accept(final Visitor v) { + v.visitVariableLengthInstruction(this); + v.visitStackConsumer(this); + v.visitBranchInstruction(this); + v.visitSelect(this); + v.visitTABLESWITCH(this); + } /** * Dump instruction as byte code to stream out. + * * @param out Output stream */ @Override - public void dump( final DataOutputStream out ) throws IOException { + public void dump(final DataOutputStream out) throws IOException { super.dump(out); - final int _match_length = getMatch_length(); - final int low = (_match_length > 0) ? super.getMatch(0) : 0; + final int matchLength = getMatchLength(); + final int low = matchLength > 0 ? super.getMatch(0) : 0; out.writeInt(low); - final int high = (_match_length > 0) ? super.getMatch(_match_length - 1) : 0; + final int high = matchLength > 0 ? super.getMatch(matchLength - 1) : 0; out.writeInt(high); - for (int i = 0; i < _match_length; i++) { + for (int i = 0; i < matchLength; i++) { out.writeInt(setIndices(i, getTargetOffset(super.getTarget(i)))); } } - /** * Read needed data (e.g. index) from file. */ @Override - protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException { + protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException { super.initFromFile(bytes, wide); final int low = bytes.readInt(); final int high = bytes.readInt(); - final int _match_length = high - low + 1; - setMatch_length(_match_length); - final short _fixed_length = (short) (13 + _match_length * 4); - setFixed_length(_fixed_length); - super.setLength((short) (_fixed_length + super.getPadding())); - super.setMatches(new int[_match_length]); - super.setIndices(new int[_match_length]); - super.setTargets(new InstructionHandle[_match_length]); - for (int i = 0; i < _match_length; i++) { + final int matchLength = high - low + 1; + setMatchLength(matchLength); + final short fixedLength = (short) (13 + matchLength * 4); + setFixedLength(fixedLength); + super.setLength((short) (fixedLength + super.getPadding())); + super.setMatches(new int[matchLength]); + super.setIndices(new int[matchLength]); + super.setTargets(new InstructionHandle[matchLength]); + for (int i = 0; i < matchLength; i++) { super.setMatch(i, low + i); super.setIndices(i, bytes.readInt()); } } - - - /** - * Call corresponding visitor method(s). The order is: - * Call visitor methods of implemented interfaces first, then - * call methods according to the class hierarchy in descending order, - * i.e., the most specific visitXXX() call comes last. - * - * @param v Visitor object - */ - @Override - public void accept( final Visitor v ) { - v.visitVariableLengthInstruction(this); - v.visitStackConsumer(this); - v.visitBranchInstruction(this); - v.visitSelect(this); - v.visitTABLESWITCH(this); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TargetLostException.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,14 +21,14 @@ package com.sun.org.apache.bcel.internal.generic; /** - * Thrown by InstructionList.remove() when one or multiple disposed instructions - * are still being referenced by an InstructionTargeter object. I.e. the - * InstructionTargeter has to be notified that (one of) the InstructionHandle it - * is referencing is being removed from the InstructionList and thus not valid anymore. + * Thrown by InstructionList.remove() when one or multiple disposed instructions are still being referenced by an + * InstructionTargeter object. I.e. the InstructionTargeter has to be notified that (one of) the InstructionHandle it is + * referencing is being removed from the InstructionList and thus not valid anymore. * - *

    Making this an exception instead of a return value forces the user to handle - * these case explicitely in a try { ... } catch. The following code illustrates - * how this may be done:

    + *

    + * Making this an exception instead of a return value forces the user to handle these case explicitly in a try { ... } + * catch. The following code illustrates how this may be done: + *

    * *
      *     ...
    @@ -47,19 +46,18 @@
      * @see InstructionHandle
      * @see InstructionList
      * @see InstructionTargeter
    + * @LastModified: Feb 2023
      */
     public final class TargetLostException extends Exception {
     
         private static final long serialVersionUID = -6857272667645328384L;
         private final InstructionHandle[] targets;
     
    -
         TargetLostException(final InstructionHandle[] t, final String mesg) {
             super(mesg);
             targets = t;
         }
     
    -
         /**
          * @return list of instructions still being targeted.
          */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/TypedInstruction.java	2023-10-06 05:33:33.000000000 +0000
    @@ -22,11 +22,9 @@
     package com.sun.org.apache.bcel.internal.generic;
     
     /**
    - * Get the type associated with an instruction, int for ILOAD, or the type
    - * of the field of a PUTFIELD instruction, e.g..
    - *
    + * Get the type associated with an instruction, int for ILOAD, or the type of the field of a PUTFIELD instruction, e.g..
      */
     public interface TypedInstruction {
     
    -    Type getType( ConstantPoolGen cpg );
    +    Type getType(ConstantPoolGen cpg);
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Type.java	2023-10-06 05:33:33.000000000 +0000
    @@ -20,26 +20,26 @@
     package com.sun.org.apache.bcel.internal.generic;
     
     import java.util.ArrayList;
    +import java.util.Arrays;
     import java.util.List;
    +import java.util.Objects;
     
     import com.sun.org.apache.bcel.internal.Const;
     import com.sun.org.apache.bcel.internal.classfile.ClassFormatException;
     import com.sun.org.apache.bcel.internal.classfile.Utility;
     
     /**
    - * Abstract super class for all possible java types, namely basic types
    - * such as int, object types like String and array types, e.g. int[]
    - *
    + * Abstract super class for all possible java types, namely basic types such as int, object types like String and array
    + * types, e.g. int[]
      * @LastModified: May 2021
      */
     public abstract class Type {
     
    -    private final byte type;
    -    private String signature; // signature for the type
         /**
          * Predefined constants
          */
         public static final BasicType VOID = new BasicType(Const.T_VOID);
    +
         public static final BasicType BOOLEAN = new BasicType(Const.T_BOOLEAN);
         public static final BasicType INT = new BasicType(Const.T_INT);
         public static final BasicType SHORT = new BasicType(Const.T_SHORT);
    @@ -53,176 +53,104 @@
         public static final ObjectType STRING = new ObjectType("java.lang.String");
         public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
         public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable");
    -    public static final Type[] NO_ARGS = new Type[0]; // EMPTY, so immutable
    -    public static final ReferenceType NULL = new ReferenceType() {
    -    };
    -    public static final Type UNKNOWN = new Type(Const.T_UNKNOWN, "") {
    -    };
    -
    -
    -    protected Type(final byte t, final String s) {
    -        type = t;
    -        signature = s;
    -    }
    -
     
         /**
    -     * @return hashcode of Type
    +     * Empty array.
          */
    -    @Override
    -    public int hashCode() {
    -        return type ^ signature.hashCode();
    -    }
    -
    +    public static final Type[] NO_ARGS = {};
    +    public static final ReferenceType NULL = new ReferenceType() {
    +    };
     
    -    /**
    -     * @return whether the Types are equal
    -     */
    -    @Override
    -    public boolean equals(final Object o) {
    -          if (o instanceof Type) {
    -              final Type t = (Type)o;
    -              return (type == t.type) && signature.equals(t.signature);
    -          }
    -          return false;
    -    }
    +    public static final Type UNKNOWN = new Type(Const.T_UNKNOWN, "") {
    +    };
     
    +    private static final ThreadLocal CONSUMED_CHARS = ThreadLocal.withInitial(() -> Integer.valueOf(0));
     
    -    /**
    -     * @return signature for given type.
    -     */
    -    public String getSignature() {
    -        return signature;
    +    // int consumed_chars=0; // Remember position in string, see getArgumentTypes
    +    static int consumed(final int coded) {
    +        return coded >> 2;
         }
     
    -
    -    /**
    -     * @return type as defined in Constants
    -     */
    -    public byte getType() {
    -        return type;
    +    static int encode(final int size, final int consumed) {
    +        return consumed << 2 | size;
         }
     
         /**
    -     * boolean, short and char variable are considered as int in the stack or local variable area.
    -     * Returns {@link Type#INT} for {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise
    -     * returns the given type.
    -     * @since 6.0
    +     * Convert arguments of a method (signature) to an array of Type objects.
    +     *
    +     * @param signature signature string such as (Ljava/lang/String;)V
    +     * @return array of argument types
          */
    -    public Type normalizeForStackOrLocal() {
    -        if (this == Type.BOOLEAN || this == Type.BYTE || this == Type.SHORT || this == Type.CHAR) {
    -            return Type.INT;
    +    public static Type[] getArgumentTypes(final String signature) {
    +        final List vec = new ArrayList<>();
    +        int index;
    +        try {
    +            // Skip any type arguments to read argument declarations between '(' and ')'
    +            index = signature.indexOf('(') + 1;
    +            if (index <= 0) {
    +                throw new ClassFormatException("Invalid method signature: " + signature);
    +            }
    +            while (signature.charAt(index) != ')') {
    +                vec.add(getType(signature.substring(index)));
    +                // corrected concurrent private static field acess
    +                index += unwrap(CONSUMED_CHARS); // update position
    +            }
    +        } catch (final StringIndexOutOfBoundsException e) { // Should never occur
    +            throw new ClassFormatException("Invalid method signature: " + signature, e);
             }
    -        return this;
    +        final Type[] types = new Type[vec.size()];
    +        vec.toArray(types);
    +        return types;
         }
     
    -    /**
    -     * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
    -     */
    -    public int getSize() {
    -        switch (type) {
    -            case Const.T_DOUBLE:
    -            case Const.T_LONG:
    -                return 2;
    -            case Const.T_VOID:
    -                return 0;
    -            default:
    -                return 1;
    +    static int getArgumentTypesSize(final String signature) {
    +        int res = 0;
    +        int index;
    +        try {
    +            // Skip any type arguments to read argument declarations between '(' and ')'
    +            index = signature.indexOf('(') + 1;
    +            if (index <= 0) {
    +                throw new ClassFormatException("Invalid method signature: " + signature);
    +            }
    +            while (signature.charAt(index) != ')') {
    +                final int coded = getTypeSize(signature.substring(index));
    +                res += size(coded);
    +                index += consumed(coded);
    +            }
    +        } catch (final StringIndexOutOfBoundsException e) { // Should never occur
    +            throw new ClassFormatException("Invalid method signature: " + signature, e);
             }
    +        return res;
         }
     
    -
    -    /**
    -     * @return Type string, e.g. `int[]'
    -     */
    -    @Override
    -    public String toString() {
    -        return ((this.equals(Type.NULL) || (type >= Const.T_UNKNOWN))) ? signature : Utility
    -                .signatureToString(signature, false);
    -    }
    -
    -
         /**
    -     * Convert type to Java method signature, e.g. int[] f(java.lang.String x)
    -     * becomes (Ljava/lang/String;)[I
    +     * Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I
          *
    -     * @param return_type what the method returns
    -     * @param arg_types what are the argument types
    +     * @param returnType what the method returns
    +     * @param argTypes what are the argument types
          * @return method signature for given type(s).
          */
    -    public static String getMethodSignature( final Type return_type, final Type[] arg_types ) {
    +    public static String getMethodSignature(final Type returnType, final Type[] argTypes) {
             final StringBuilder buf = new StringBuilder("(");
    -        if (arg_types != null) {
    -            for (final Type arg_type : arg_types) {
    -                buf.append(arg_type.getSignature());
    +        if (argTypes != null) {
    +            for (final Type argType : argTypes) {
    +                buf.append(argType.getSignature());
                 }
             }
             buf.append(')');
    -        buf.append(return_type.getSignature());
    +        buf.append(returnType.getSignature());
             return buf.toString();
         }
     
    -    private static final ThreadLocal consumed_chars = new ThreadLocal() {
    -
    -        @Override
    -        protected Integer initialValue() {
    -            return Integer.valueOf(0);
    -        }
    -    };//int consumed_chars=0; // Remember position in string, see getArgumentTypes
    -
    -
    -    private static int unwrap( final ThreadLocal tl ) {
    -        return tl.get().intValue();
    -    }
    -
    -
    -    private static void wrap( final ThreadLocal tl, final int value ) {
    -        tl.set(Integer.valueOf(value));
    -    }
    -
    -
    -    /**
    -     * Convert signature to a Type object.
    -     * @param signature signature string such as Ljava/lang/String;
    -     * @return type object
    -     */
    -    // @since 6.0 no longer final
    -    public static Type getType( final String signature ) throws StringIndexOutOfBoundsException {
    -        final byte type = Utility.typeOfSignature(signature);
    -        if (type <= Const.T_VOID) {
    -            //corrected concurrent private static field acess
    -            wrap(consumed_chars, 1);
    -            return BasicType.getType(type);
    -        } else if (type == Const.T_ARRAY) {
    -            int dim = 0;
    -            do { // Count dimensions
    -                dim++;
    -            } while (signature.charAt(dim) == '[');
    -            // Recurse, but just once, if the signature is ok
    -            final Type t = getType(signature.substring(dim));
    -            //corrected concurrent private static field acess
    -            //  consumed_chars += dim; // update counter - is replaced by
    -            final int _temp = unwrap(consumed_chars) + dim;
    -            wrap(consumed_chars, _temp);
    -            return new ArrayType(t, dim);
    -        } else { // type == T_REFERENCE
    -            // Utility.typeSignatureToString understands how to parse generic types.
    -            final String parsedSignature = Utility.typeSignatureToString(signature, false);
    -            wrap(consumed_chars, parsedSignature.length() + 2); // "Lblabla;" `L' and `;' are removed
    -            return ObjectType.getInstance(parsedSignature.replace('/', '.'));
    -        }
    -    }
    -
    -
         /**
          * Convert return value of a method (signature) to a Type object.
          *
          * @param signature signature string such as (Ljava/lang/String;)V
          * @return return type
          */
    -    public static Type getReturnType( final String signature ) {
    +    public static Type getReturnType(final String signature) {
             try {
    -            // Read return type after `)'
    +            // Read return type after ')'
                 final int index = signature.lastIndexOf(')') + 1;
                 return getType(signature.substring(index));
             } catch (final StringIndexOutOfBoundsException e) { // Should never occur
    @@ -230,170 +158,242 @@
             }
         }
     
    +    static int getReturnTypeSize(final String signature) {
    +        final int index = signature.lastIndexOf(')') + 1;
    +        return Type.size(getTypeSize(signature.substring(index)));
    +    }
     
    -    /**
    -     * Convert arguments of a method (signature) to an array of Type objects.
    -     * @param signature signature string such as (Ljava/lang/String;)V
    -     * @return array of argument types
    -     */
    -    public static Type[] getArgumentTypes( final String signature ) {
    -        final List vec = new ArrayList<>();
    -        int index;
    -        Type[] types;
    -        try {
    -            // Skip any type arguments to read argument declarations between `(' and `)'
    -            index = signature.indexOf('(') + 1;
    -            if (index <= 0) {
    -                throw new ClassFormatException("Invalid method signature: " + signature);
    -            }
    -            while (signature.charAt(index) != ')') {
    -                vec.add(getType(signature.substring(index)));
    -                //corrected concurrent private static field acess
    -                index += unwrap(consumed_chars); // update position
    -            }
    -        } catch (final StringIndexOutOfBoundsException e) { // Should never occur
    -            throw new ClassFormatException("Invalid method signature: " + signature, e);
    +    public static String getSignature(final java.lang.reflect.Method meth) {
    +        final StringBuilder sb = new StringBuilder("(");
    +        final Class[] params = meth.getParameterTypes(); // avoid clone
    +        for (final Class param : params) {
    +            sb.append(getType(param).getSignature());
             }
    -        types = new Type[vec.size()];
    -        vec.toArray(types);
    -        return types;
    +        sb.append(")");
    +        sb.append(getType(meth.getReturnType()).getSignature());
    +        return sb.toString();
         }
     
    -
    -    /** Convert runtime java.lang.Class to BCEL Type object.
    -     * @param cl Java class
    +    /**
    +     * Convert runtime java.lang.Class to BCEL Type object.
    +     *
    +     * @param cls Java class
          * @return corresponding Type object
          */
    -    public static Type getType( final java.lang.Class cl ) {
    -        if (cl == null) {
    -            throw new IllegalArgumentException("Class must not be null");
    -        }
    -        /* That's an amzingly easy case, because getName() returns
    -         * the signature. That's what we would have liked anyway.
    +    public static Type getType(final Class cls) {
    +        Objects.requireNonNull(cls, "cls");
    +        /*
    +         * That's an amzingly easy case, because getName() returns the signature. That's what we would have liked anyway.
              */
    -        if (cl.isArray()) {
    -            return getType(cl.getName());
    -        } else if (cl.isPrimitive()) {
    -            if (cl == Integer.TYPE) {
    -                return INT;
    -            } else if (cl == Void.TYPE) {
    -                return VOID;
    -            } else if (cl == Double.TYPE) {
    -                return DOUBLE;
    -            } else if (cl == Float.TYPE) {
    -                return FLOAT;
    -            } else if (cl == Boolean.TYPE) {
    -                return BOOLEAN;
    -            } else if (cl == Byte.TYPE) {
    -                return BYTE;
    -            } else if (cl == Short.TYPE) {
    -                return SHORT;
    -            } else if (cl == Byte.TYPE) {
    -                return BYTE;
    -            } else if (cl == Long.TYPE) {
    -                return LONG;
    -            } else if (cl == Character.TYPE) {
    -                return CHAR;
    -            } else {
    -                throw new IllegalStateException("Unknown primitive type " + cl);
    -            }
    -        } else { // "Real" class
    -            return ObjectType.getInstance(cl.getName());
    +        if (cls.isArray()) {
    +            return getType(cls.getName());
    +        }
    +        if (!cls.isPrimitive()) { // "Real" class
    +            return ObjectType.getInstance(cls.getName());
    +        }
    +        if (cls == Integer.TYPE) {
    +            return INT;
    +        }
    +        if (cls == Void.TYPE) {
    +            return VOID;
    +        }
    +        if (cls == Double.TYPE) {
    +            return DOUBLE;
    +        }
    +        if (cls == Float.TYPE) {
    +            return FLOAT;
    +        }
    +        if (cls == Boolean.TYPE) {
    +            return BOOLEAN;
    +        }
    +        if (cls == Byte.TYPE) {
    +            return BYTE;
    +        }
    +        if (cls == Short.TYPE) {
    +            return SHORT;
    +        }
    +        if (cls == Long.TYPE) {
    +            return LONG;
             }
    +        if (cls == Character.TYPE) {
    +            return CHAR;
    +        }
    +        throw new IllegalStateException("Unknown primitive type " + cls);
         }
     
    +    /**
    +     * Convert signature to a Type object.
    +     *
    +     * @param signature signature string such as Ljava/lang/String;
    +     * @return type object
    +     */
    +    public static Type getType(final String signature) throws StringIndexOutOfBoundsException {
    +        final byte type = Utility.typeOfSignature(signature);
    +        if (type <= Const.T_VOID) {
    +            // corrected concurrent private static field acess
    +            wrap(CONSUMED_CHARS, 1);
    +            return BasicType.getType(type);
    +        }
    +        if (type != Const.T_ARRAY) { // type == T_REFERENCE
    +            // Utility.typeSignatureToString understands how to parse generic types.
    +            final String parsedSignature = Utility.typeSignatureToString(signature, false);
    +            wrap(CONSUMED_CHARS, parsedSignature.length() + 2); // "Lblabla;" 'L' and ';' are removed
    +            return ObjectType.getInstance(Utility.pathToPackage(parsedSignature));
    +        }
    +        int dim = 0;
    +        do { // Count dimensions
    +            dim++;
    +        } while (signature.charAt(dim) == '[');
    +        // Recurse, but just once, if the signature is ok
    +        final Type t = getType(signature.substring(dim));
    +        // corrected concurrent private static field acess
    +        // consumed_chars += dim; // update counter - is replaced by
    +        final int temp = unwrap(CONSUMED_CHARS) + dim;
    +        wrap(CONSUMED_CHARS, temp);
    +        return new ArrayType(t, dim);
    +    }
     
         /**
          * Convert runtime java.lang.Class[] to BCEL Type objects.
    +     *
          * @param classes an array of runtime class objects
          * @return array of corresponding Type objects
          */
    -    public static Type[] getTypes( final java.lang.Class[] classes ) {
    +    public static Type[] getTypes(final Class[] classes) {
             final Type[] ret = new Type[classes.length];
    -        for (int i = 0; i < ret.length; i++) {
    -            ret[i] = getType(classes[i]);
    -        }
    +        Arrays.setAll(ret, i -> getType(classes[i]));
             return ret;
         }
     
    -
    -    public static String getSignature( final java.lang.reflect.Method meth ) {
    -        final StringBuilder sb = new StringBuilder("(");
    -        final Class[] params = meth.getParameterTypes(); // avoid clone
    -        for (final Class param : params) {
    -            sb.append(getType(param).getSignature());
    +    static int getTypeSize(final String signature) throws StringIndexOutOfBoundsException {
    +        final byte type = Utility.typeOfSignature(signature);
    +        if (type <= Const.T_VOID) {
    +            return encode(BasicType.getType(type).getSize(), 1);
             }
    -        sb.append(")");
    -        sb.append(getType(meth.getReturnType()).getSignature());
    -        return sb.toString();
    +        if (type == Const.T_ARRAY) {
    +            int dim = 0;
    +            do { // Count dimensions
    +                dim++;
    +            } while (signature.charAt(dim) == '[');
    +            // Recurse, but just once, if the signature is ok
    +            final int consumed = consumed(getTypeSize(signature.substring(dim)));
    +            return encode(1, dim + consumed);
    +        }
    +        final int index = signature.indexOf(';'); // Look for closing ';'
    +        if (index < 0) {
    +            throw new ClassFormatException("Invalid signature: " + signature);
    +        }
    +        return encode(1, index + 1);
         }
     
         static int size(final int coded) {
             return coded & 3;
         }
     
    -    static int consumed(final int coded) {
    -        return coded >> 2;
    +    private static int unwrap(final ThreadLocal tl) {
    +        return tl.get().intValue();
         }
     
    -    static int encode(final int size, final int consumed) {
    -        return consumed << 2 | size;
    +    private static void wrap(final ThreadLocal tl, final int value) {
    +        tl.set(Integer.valueOf(value));
         }
     
    -    static int getArgumentTypesSize( final String signature ) {
    -        int res = 0;
    -        int index;
    -        try {
    -            // Skip any type arguments to read argument declarations between `(' and `)'
    -            index = signature.indexOf('(') + 1;
    -            if (index <= 0) {
    -                throw new ClassFormatException("Invalid method signature: " + signature);
    -            }
    -            while (signature.charAt(index) != ')') {
    -                final int coded = getTypeSize(signature.substring(index));
    -                res += size(coded);
    -                index += consumed(coded);
    -            }
    -        } catch (final StringIndexOutOfBoundsException e) { // Should never occur
    -            throw new ClassFormatException("Invalid method signature: " + signature, e);
    +    /**
    +     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
    +     */
    +    @Deprecated
    +    protected byte type; // TODO should be final (and private)
    +
    +    /**
    +     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
    +     */
    +    @Deprecated
    +    protected String signature; // signature for the type TODO should be private
    +
    +    protected Type(final byte type, final String signature) {
    +        this.type = type;
    +        this.signature = signature;
    +    }
    +
    +    /**
    +     * @return whether the Types are equal
    +     */
    +    @Override
    +    public boolean equals(final Object o) {
    +        if (o instanceof Type) {
    +            final Type t = (Type) o;
    +            return type == t.type && signature.equals(t.signature);
             }
    -        return res;
    +        return false;
         }
     
    -    static int getTypeSize( final String signature ) throws StringIndexOutOfBoundsException {
    -        final byte type = Utility.typeOfSignature(signature);
    -        if (type <= Const.T_VOID) {
    -            return encode(BasicType.getType(type).getSize(), 1);
    -        } else if (type == Const.T_ARRAY) {
    -            int dim = 0;
    -            do { // Count dimensions
    -                dim++;
    -            } while (signature.charAt(dim) == '[');
    -            // Recurse, but just once, if the signature is ok
    -            final int consumed = consumed(getTypeSize(signature.substring(dim)));
    -            return encode(1, dim + consumed);
    -        } else { // type == T_REFERENCE
    -            final int index = signature.indexOf(';'); // Look for closing `;'
    -            if (index < 0) {
    -                throw new ClassFormatException("Invalid signature: " + signature);
    -            }
    -            return encode(1, index + 1);
    +    public String getClassName() {
    +        return toString();
    +    }
    +
    +    /**
    +     * @return signature for given type.
    +     */
    +    public String getSignature() {
    +        return signature;
    +    }
    +
    +    /**
    +     * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
    +     */
    +    public int getSize() {
    +        switch (type) {
    +        case Const.T_DOUBLE:
    +        case Const.T_LONG:
    +            return 2;
    +        case Const.T_VOID:
    +            return 0;
    +        default:
    +            return 1;
             }
         }
     
    +    /**
    +     * @return type as defined in Constants
    +     */
    +    public byte getType() {
    +        return type;
    +    }
     
    -    static int getReturnTypeSize(final String signature) {
    -        final int index = signature.lastIndexOf(')') + 1;
    -        return Type.size(getTypeSize(signature.substring(index)));
    +    /**
    +     * @return hashcode of Type
    +     */
    +    @Override
    +    public int hashCode() {
    +        return type ^ signature.hashCode();
         }
     
    +    /**
    +     * boolean, short and char variable are considered as int in the stack or local variable area. Returns {@link Type#INT}
    +     * for {@link Type#BOOLEAN}, {@link Type#SHORT} or {@link Type#CHAR}, otherwise returns the given type.
    +     *
    +     * @since 6.0
    +     */
    +    public Type normalizeForStackOrLocal() {
    +        if (this == Type.BOOLEAN || this == Type.BYTE || this == Type.SHORT || this == Type.CHAR) {
    +            return Type.INT;
    +        }
    +        return this;
    +    }
     
         /*
    -     * Currently only used by the ArrayType constructor.
    -     * The signature has a complicated dependency on other parameter
    -     * so it's tricky to do it in a call to the super ctor.
    +     * Currently only used by the ArrayType constructor. The signature has a complicated dependency on other parameter so
    +     * it's tricky to do it in a call to the super ctor.
          */
         void setSignature(final String signature) {
             this.signature = signature;
         }
    +
    +    /**
    +     * @return Type string, e.g. 'int[]'
    +     */
    +    @Override
    +    public String toString() {
    +        return this.equals(Type.NULL) || type >= Const.T_UNKNOWN ? signature : Utility.signatureToString(signature, false);
    +    }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/UnconditionalBranch.java	2023-10-06 05:33:33.000000000 +0000
    @@ -24,7 +24,6 @@
     /**
      * Denotes an instruction to perform an unconditional branch, i.e., GOTO, JSR.
      *
    -
      * @see GOTO
      * @see JSR
      */
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/VariableLengthInstruction.java	2023-10-06 05:33:33.000000000 +0000
    @@ -22,10 +22,9 @@
     package com.sun.org.apache.bcel.internal.generic;
     
     /**
    - * Denotes an instruction to be a variable length instruction, such as
    - * GOTO, JSR, LOOKUPSWITCH and TABLESWITCH.
    + * Denotes an instruction to be a variable length instruction, such as GOTO, JSR, LOOKUPSWITCH and TABLESWITCH.
    + *
      *
    -
      * @see GOTO
      * @see JSR
      * @see LOOKUPSWITCH
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/generic/Visitor.java	2023-10-06 05:33:33.000000000 +0000
    @@ -22,556 +22,373 @@
     package com.sun.org.apache.bcel.internal.generic;
     
     /**
    - * Interface implementing the Visitor pattern programming style.
    - * I.e., a class that implements this interface can handle all types of
    - * instructions with the properly typed methods just by calling the accept()
    - * method.
    - *
    + * Interface implementing the Visitor pattern programming style. I.e., a class that implements this interface can handle
    + * all types of instructions with the properly typed methods just by calling the accept() method.
      */
     public interface Visitor {
     
    -    void visitStackInstruction( StackInstruction obj );
    +    void visitAALOAD(AALOAD obj);
     
    +    void visitAASTORE(AASTORE obj);
     
    -    void visitLocalVariableInstruction( LocalVariableInstruction obj );
    +    void visitACONST_NULL(ACONST_NULL obj);
     
    +    void visitAllocationInstruction(AllocationInstruction obj);
     
    -    void visitBranchInstruction( BranchInstruction obj );
    +    void visitALOAD(ALOAD obj);
     
    +    void visitANEWARRAY(ANEWARRAY obj);
     
    -    void visitLoadClass( LoadClass obj );
    +    void visitARETURN(ARETURN obj);
     
    +    void visitArithmeticInstruction(ArithmeticInstruction obj);
     
    -    void visitFieldInstruction( FieldInstruction obj );
    +    void visitArrayInstruction(ArrayInstruction obj);
     
    +    void visitARRAYLENGTH(ARRAYLENGTH obj);
     
    -    void visitIfInstruction( IfInstruction obj );
    +    void visitASTORE(ASTORE obj);
     
    +    void visitATHROW(ATHROW obj);
     
    -    void visitConversionInstruction( ConversionInstruction obj );
    +    void visitBALOAD(BALOAD obj);
     
    +    void visitBASTORE(BASTORE obj);
     
    -    void visitPopInstruction( PopInstruction obj );
    +    void visitBIPUSH(BIPUSH obj);
     
    +    void visitBranchInstruction(BranchInstruction obj);
     
    -    void visitStoreInstruction( StoreInstruction obj );
    +    void visitBREAKPOINT(BREAKPOINT obj);
     
    +    void visitCALOAD(CALOAD obj);
     
    -    void visitTypedInstruction( TypedInstruction obj );
    +    void visitCASTORE(CASTORE obj);
     
    +    void visitCHECKCAST(CHECKCAST obj);
     
    -    void visitSelect( Select obj );
    +    void visitConstantPushInstruction(ConstantPushInstruction obj);
     
    +    void visitConversionInstruction(ConversionInstruction obj);
     
    -    void visitJsrInstruction( JsrInstruction obj );
    +    void visitCPInstruction(CPInstruction obj);
     
    +    void visitD2F(D2F obj);
     
    -    void visitGotoInstruction( GotoInstruction obj );
    +    void visitD2I(D2I obj);
     
    +    void visitD2L(D2L obj);
     
    -    void visitUnconditionalBranch( UnconditionalBranch obj );
    +    void visitDADD(DADD obj);
     
    +    void visitDALOAD(DALOAD obj);
     
    -    void visitPushInstruction( PushInstruction obj );
    +    void visitDASTORE(DASTORE obj);
     
    +    void visitDCMPG(DCMPG obj);
     
    -    void visitArithmeticInstruction( ArithmeticInstruction obj );
    +    void visitDCMPL(DCMPL obj);
     
    +    void visitDCONST(DCONST obj);
     
    -    void visitCPInstruction( CPInstruction obj );
    +    void visitDDIV(DDIV obj);
     
    +    void visitDLOAD(DLOAD obj);
     
    -    void visitInvokeInstruction( InvokeInstruction obj );
    +    void visitDMUL(DMUL obj);
     
    +    void visitDNEG(DNEG obj);
     
    -    void visitArrayInstruction( ArrayInstruction obj );
    +    void visitDREM(DREM obj);
     
    +    void visitDRETURN(DRETURN obj);
     
    -    void visitAllocationInstruction( AllocationInstruction obj );
    +    void visitDSTORE(DSTORE obj);
     
    +    void visitDSUB(DSUB obj);
     
    -    void visitReturnInstruction( ReturnInstruction obj );
    +    void visitDUP(DUP obj);
     
    +    void visitDUP_X1(DUP_X1 obj);
     
    -    void visitFieldOrMethod( FieldOrMethod obj );
    +    void visitDUP_X2(DUP_X2 obj);
     
    +    void visitDUP2(DUP2 obj);
     
    -    void visitConstantPushInstruction( ConstantPushInstruction obj );
    +    void visitDUP2_X1(DUP2_X1 obj);
     
    +    void visitDUP2_X2(DUP2_X2 obj);
     
    -    void visitExceptionThrower( ExceptionThrower obj );
    +    void visitExceptionThrower(ExceptionThrower obj);
     
    +    void visitF2D(F2D obj);
     
    -    void visitLoadInstruction( LoadInstruction obj );
    +    void visitF2I(F2I obj);
     
    +    void visitF2L(F2L obj);
     
    -    void visitVariableLengthInstruction( VariableLengthInstruction obj );
    +    void visitFADD(FADD obj);
     
    +    void visitFALOAD(FALOAD obj);
     
    -    void visitStackProducer( StackProducer obj );
    +    void visitFASTORE(FASTORE obj);
     
    +    void visitFCMPG(FCMPG obj);
     
    -    void visitStackConsumer( StackConsumer obj );
    +    void visitFCMPL(FCMPL obj);
     
    +    void visitFCONST(FCONST obj);
     
    -    void visitACONST_NULL( ACONST_NULL obj );
    +    void visitFDIV(FDIV obj);
     
    +    void visitFieldInstruction(FieldInstruction obj);
     
    -    void visitGETSTATIC( GETSTATIC obj );
    +    void visitFieldOrMethod(FieldOrMethod obj);
     
    +    void visitFLOAD(FLOAD obj);
     
    -    void visitIF_ICMPLT( IF_ICMPLT obj );
    +    void visitFMUL(FMUL obj);
     
    +    void visitFNEG(FNEG obj);
     
    -    void visitMONITOREXIT( MONITOREXIT obj );
    +    void visitFREM(FREM obj);
     
    +    void visitFRETURN(FRETURN obj);
     
    -    void visitIFLT( IFLT obj );
    +    void visitFSTORE(FSTORE obj);
     
    +    void visitFSUB(FSUB obj);
     
    -    void visitLSTORE( LSTORE obj );
    +    void visitGETFIELD(GETFIELD obj);
     
    +    void visitGETSTATIC(GETSTATIC obj);
     
    -    void visitPOP2( POP2 obj );
    +    void visitGOTO(GOTO obj);
     
    +    void visitGOTO_W(GOTO_W obj);
     
    -    void visitBASTORE( BASTORE obj );
    +    void visitGotoInstruction(GotoInstruction obj);
     
    +    void visitI2B(I2B obj);
     
    -    void visitISTORE( ISTORE obj );
    +    void visitI2C(I2C obj);
     
    +    void visitI2D(I2D obj);
     
    -    void visitCHECKCAST( CHECKCAST obj );
    +    void visitI2F(I2F obj);
     
    +    void visitI2L(I2L obj);
     
    -    void visitFCMPG( FCMPG obj );
    +    void visitI2S(I2S obj);
     
    +    void visitIADD(IADD obj);
     
    -    void visitI2F( I2F obj );
    +    void visitIALOAD(IALOAD obj);
     
    +    void visitIAND(IAND obj);
     
    -    void visitATHROW( ATHROW obj );
    +    void visitIASTORE(IASTORE obj);
     
    +    void visitICONST(ICONST obj);
     
    -    void visitDCMPL( DCMPL obj );
    +    void visitIDIV(IDIV obj);
     
    +    void visitIF_ACMPEQ(IF_ACMPEQ obj);
     
    -    void visitARRAYLENGTH( ARRAYLENGTH obj );
    +    void visitIF_ACMPNE(IF_ACMPNE obj);
     
    +    void visitIF_ICMPEQ(IF_ICMPEQ obj);
     
    -    void visitDUP( DUP obj );
    +    void visitIF_ICMPGE(IF_ICMPGE obj);
     
    +    void visitIF_ICMPGT(IF_ICMPGT obj);
     
    -    void visitINVOKESTATIC( INVOKESTATIC obj );
    +    void visitIF_ICMPLE(IF_ICMPLE obj);
     
    +    void visitIF_ICMPLT(IF_ICMPLT obj);
     
    -    void visitLCONST( LCONST obj );
    +    void visitIF_ICMPNE(IF_ICMPNE obj);
     
    +    void visitIFEQ(IFEQ obj);
     
    -    void visitDREM( DREM obj );
    +    void visitIFGE(IFGE obj);
     
    +    void visitIFGT(IFGT obj);
     
    -    void visitIFGE( IFGE obj );
    +    void visitIfInstruction(IfInstruction obj);
     
    +    void visitIFLE(IFLE obj);
     
    -    void visitCALOAD( CALOAD obj );
    +    void visitIFLT(IFLT obj);
     
    +    void visitIFNE(IFNE obj);
     
    -    void visitLASTORE( LASTORE obj );
    +    void visitIFNONNULL(IFNONNULL obj);
     
    +    void visitIFNULL(IFNULL obj);
     
    -    void visitI2D( I2D obj );
    +    void visitIINC(IINC obj);
     
    +    void visitILOAD(ILOAD obj);
     
    -    void visitDADD( DADD obj );
    +    void visitIMPDEP1(IMPDEP1 obj);
     
    +    void visitIMPDEP2(IMPDEP2 obj);
     
    -    void visitINVOKESPECIAL( INVOKESPECIAL obj );
    +    void visitIMUL(IMUL obj);
     
    +    void visitINEG(INEG obj);
     
    -    void visitIAND( IAND obj );
    -
    -
    -    void visitPUTFIELD( PUTFIELD obj );
    -
    -
    -    void visitILOAD( ILOAD obj );
    -
    -
    -    void visitDLOAD( DLOAD obj );
    -
    -
    -    void visitDCONST( DCONST obj );
    -
    -
    -    void visitNEW( NEW obj );
    -
    -
    -    void visitIFNULL( IFNULL obj );
    -
    -
    -    void visitLSUB( LSUB obj );
    -
    -
    -    void visitL2I( L2I obj );
    -
    -
    -    void visitISHR( ISHR obj );
    -
    -
    -    void visitTABLESWITCH( TABLESWITCH obj );
    -
    -
    -    void visitIINC( IINC obj );
    -
    -
    -    void visitDRETURN( DRETURN obj );
    -
    -
    -    void visitFSTORE( FSTORE obj );
    -
    -
    -    void visitDASTORE( DASTORE obj );
    -
    -
    -    void visitIALOAD( IALOAD obj );
    -
    -
    -    void visitDDIV( DDIV obj );
    -
    -
    -    void visitIF_ICMPGE( IF_ICMPGE obj );
    -
    -
    -    void visitLAND( LAND obj );
    -
    -
    -    void visitIDIV( IDIV obj );
    -
    -
    -    void visitLOR( LOR obj );
    -
    -
    -    void visitCASTORE( CASTORE obj );
    -
    -
    -    void visitFREM( FREM obj );
    -
    -
    -    void visitLDC( LDC obj );
    -
    -
    -    void visitBIPUSH( BIPUSH obj );
    -
    -
    -    void visitDSTORE( DSTORE obj );
    -
    -
    -    void visitF2L( F2L obj );
    -
    -
    -    void visitFMUL( FMUL obj );
    -
    -
    -    void visitLLOAD( LLOAD obj );
    -
    -
    -    void visitJSR( JSR obj );
    -
    -
    -    void visitFSUB( FSUB obj );
    -
    -
    -    void visitSASTORE( SASTORE obj );
    -
    -
    -    void visitALOAD( ALOAD obj );
    -
    -
    -    void visitDUP2_X2( DUP2_X2 obj );
    -
    -
    -    void visitRETURN( RETURN obj );
    -
    -
    -    void visitDALOAD( DALOAD obj );
    -
    -
    -    void visitSIPUSH( SIPUSH obj );
    -
    -
    -    void visitDSUB( DSUB obj );
    -
    -
    -    void visitL2F( L2F obj );
    -
    -
    -    void visitIF_ICMPGT( IF_ICMPGT obj );
    -
    -
    -    void visitF2D( F2D obj );
    -
    -
    -    void visitI2L( I2L obj );
    -
    -
    -    void visitIF_ACMPNE( IF_ACMPNE obj );
    -
    -
    -    void visitPOP( POP obj );
    -
    -
    -    void visitI2S( I2S obj );
    -
    -
    -    void visitIFEQ( IFEQ obj );
    -
    -
    -    void visitSWAP( SWAP obj );
    -
    -
    -    void visitIOR( IOR obj );
    -
    -
    -    void visitIREM( IREM obj );
    -
    -
    -    void visitIASTORE( IASTORE obj );
    -
    -
    -    void visitNEWARRAY( NEWARRAY obj );
    -
    -
    -    void visitINVOKEINTERFACE( INVOKEINTERFACE obj );
    -
    -
    -    void visitINEG( INEG obj );
    -
    -
    -    void visitLCMP( LCMP obj );
    -
    -
    -    void visitJSR_W( JSR_W obj );
    -
    -
    -    void visitMULTIANEWARRAY( MULTIANEWARRAY obj );
    -
    -
    -    void visitDUP_X2( DUP_X2 obj );
    -
    -
    -    void visitSALOAD( SALOAD obj );
    -
    -
    -    void visitIFNONNULL( IFNONNULL obj );
    -
    -
    -    void visitDMUL( DMUL obj );
    -
    -
    -    void visitIFNE( IFNE obj );
    -
    -
    -    void visitIF_ICMPLE( IF_ICMPLE obj );
    -
    -
    -    void visitLDC2_W( LDC2_W obj );
    -
    -
    -    void visitGETFIELD( GETFIELD obj );
    -
    -
    -    void visitLADD( LADD obj );
    -
    -
    -    void visitNOP( NOP obj );
    -
    -
    -    void visitFALOAD( FALOAD obj );
    -
    -
    -    void visitINSTANCEOF( INSTANCEOF obj );
    -
    -
    -    void visitIFLE( IFLE obj );
    -
    -
    -    void visitLXOR( LXOR obj );
    -
    -
    -    void visitLRETURN( LRETURN obj );
    -
    -
    -    void visitFCONST( FCONST obj );
    -
    -
    -    void visitIUSHR( IUSHR obj );
    -
    -
    -    void visitBALOAD( BALOAD obj );
    -
    -
    -    void visitDUP2( DUP2 obj );
    -
    -
    -    void visitIF_ACMPEQ( IF_ACMPEQ obj );
    -
    -
    -    void visitIMPDEP1( IMPDEP1 obj );
    -
    -
    -    void visitMONITORENTER( MONITORENTER obj );
    -
    -
    -    void visitLSHL( LSHL obj );
    -
    -
    -    void visitDCMPG( DCMPG obj );
    -
    -
    -    void visitD2L( D2L obj );
    -
    -
    -    void visitIMPDEP2( IMPDEP2 obj );
    -
    -
    -    void visitL2D( L2D obj );
    -
    -
    -    void visitRET( RET obj );
    -
    -
    -    void visitIFGT( IFGT obj );
    -
    -
    -    void visitIXOR( IXOR obj );
    -
    -
    -    void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj );
    -
    +    void visitINSTANCEOF(INSTANCEOF obj);
     
         /**
          * @since 6.0
          */
    -    void visitINVOKEDYNAMIC( INVOKEDYNAMIC obj );
    -
    -
    -    void visitFASTORE( FASTORE obj );
    -
    -
    -    void visitIRETURN( IRETURN obj );
    -
    -
    -    void visitIF_ICMPNE( IF_ICMPNE obj );
    -
    +    void visitINVOKEDYNAMIC(INVOKEDYNAMIC obj);
     
    -    void visitFLOAD( FLOAD obj );
    +    void visitInvokeInstruction(InvokeInstruction obj);
     
    +    void visitINVOKEINTERFACE(INVOKEINTERFACE obj);
     
    -    void visitLDIV( LDIV obj );
    +    void visitINVOKESPECIAL(INVOKESPECIAL obj);
     
    +    void visitINVOKESTATIC(INVOKESTATIC obj);
     
    -    void visitPUTSTATIC( PUTSTATIC obj );
    +    void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj);
     
    +    void visitIOR(IOR obj);
     
    -    void visitAALOAD( AALOAD obj );
    +    void visitIREM(IREM obj);
     
    +    void visitIRETURN(IRETURN obj);
     
    -    void visitD2I( D2I obj );
    +    void visitISHL(ISHL obj);
     
    +    void visitISHR(ISHR obj);
     
    -    void visitIF_ICMPEQ( IF_ICMPEQ obj );
    +    void visitISTORE(ISTORE obj);
     
    +    void visitISUB(ISUB obj);
     
    -    void visitAASTORE( AASTORE obj );
    +    void visitIUSHR(IUSHR obj);
     
    +    void visitIXOR(IXOR obj);
     
    -    void visitARETURN( ARETURN obj );
    +    void visitJSR(JSR obj);
     
    +    void visitJSR_W(JSR_W obj);
     
    -    void visitDUP2_X1( DUP2_X1 obj );
    +    void visitJsrInstruction(JsrInstruction obj);
     
    +    void visitL2D(L2D obj);
     
    -    void visitFNEG( FNEG obj );
    +    void visitL2F(L2F obj);
     
    +    void visitL2I(L2I obj);
     
    -    void visitGOTO_W( GOTO_W obj );
    +    void visitLADD(LADD obj);
     
    +    void visitLALOAD(LALOAD obj);
     
    -    void visitD2F( D2F obj );
    +    void visitLAND(LAND obj);
     
    +    void visitLASTORE(LASTORE obj);
     
    -    void visitGOTO( GOTO obj );
    +    void visitLCMP(LCMP obj);
     
    +    void visitLCONST(LCONST obj);
     
    -    void visitISUB( ISUB obj );
    +    void visitLDC(LDC obj);
     
    +    void visitLDC2_W(LDC2_W obj);
     
    -    void visitF2I( F2I obj );
    +    void visitLDIV(LDIV obj);
     
    +    void visitLLOAD(LLOAD obj);
     
    -    void visitDNEG( DNEG obj );
    +    void visitLMUL(LMUL obj);
     
    +    void visitLNEG(LNEG obj);
     
    -    void visitICONST( ICONST obj );
    +    void visitLoadClass(LoadClass obj);
     
    +    void visitLoadInstruction(LoadInstruction obj);
     
    -    void visitFDIV( FDIV obj );
    +    void visitLocalVariableInstruction(LocalVariableInstruction obj);
     
    +    void visitLOOKUPSWITCH(LOOKUPSWITCH obj);
     
    -    void visitI2B( I2B obj );
    +    void visitLOR(LOR obj);
     
    +    void visitLREM(LREM obj);
     
    -    void visitLNEG( LNEG obj );
    +    void visitLRETURN(LRETURN obj);
     
    +    void visitLSHL(LSHL obj);
     
    -    void visitLREM( LREM obj );
    +    void visitLSHR(LSHR obj);
     
    +    void visitLSTORE(LSTORE obj);
     
    -    void visitIMUL( IMUL obj );
    +    void visitLSUB(LSUB obj);
     
    +    void visitLUSHR(LUSHR obj);
     
    -    void visitIADD( IADD obj );
    +    void visitLXOR(LXOR obj);
     
    +    void visitMONITORENTER(MONITORENTER obj);
     
    -    void visitLSHR( LSHR obj );
    +    void visitMONITOREXIT(MONITOREXIT obj);
     
    +    void visitMULTIANEWARRAY(MULTIANEWARRAY obj);
     
    -    void visitLOOKUPSWITCH( LOOKUPSWITCH obj );
    +    void visitNEW(NEW obj);
     
    +    void visitNEWARRAY(NEWARRAY obj);
     
    -    void visitDUP_X1( DUP_X1 obj );
    +    void visitNOP(NOP obj);
     
    +    void visitPOP(POP obj);
     
    -    void visitFCMPL( FCMPL obj );
    +    void visitPOP2(POP2 obj);
     
    +    void visitPopInstruction(PopInstruction obj);
     
    -    void visitI2C( I2C obj );
    +    void visitPushInstruction(PushInstruction obj);
     
    +    void visitPUTFIELD(PUTFIELD obj);
     
    -    void visitLMUL( LMUL obj );
    +    void visitPUTSTATIC(PUTSTATIC obj);
     
    +    void visitRET(RET obj);
     
    -    void visitLUSHR( LUSHR obj );
    +    void visitRETURN(RETURN obj);
     
    +    void visitReturnInstruction(ReturnInstruction obj);
     
    -    void visitISHL( ISHL obj );
    +    void visitSALOAD(SALOAD obj);
     
    +    void visitSASTORE(SASTORE obj);
     
    -    void visitLALOAD( LALOAD obj );
    +    void visitSelect(Select obj);
     
    +    void visitSIPUSH(SIPUSH obj);
     
    -    void visitASTORE( ASTORE obj );
    +    void visitStackConsumer(StackConsumer obj);
     
    +    void visitStackInstruction(StackInstruction obj);
     
    -    void visitANEWARRAY( ANEWARRAY obj );
    +    void visitStackProducer(StackProducer obj);
     
    +    void visitStoreInstruction(StoreInstruction obj);
     
    -    void visitFRETURN( FRETURN obj );
    +    void visitSWAP(SWAP obj);
     
    +    void visitTABLESWITCH(TABLESWITCH obj);
     
    -    void visitFADD( FADD obj );
    +    void visitTypedInstruction(TypedInstruction obj);
     
    +    void visitUnconditionalBranch(UnconditionalBranch obj);
     
    -    void visitBREAKPOINT( BREAKPOINT obj );
    +    void visitVariableLengthInstruction(VariableLengthInstruction obj);
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/Repository.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
      */
     /*
      * Licensed to the Apache Software Foundation (ASF) under one or more
    @@ -24,227 +24,183 @@
     import com.sun.org.apache.bcel.internal.util.SyntheticRepository;
     
     /**
    - * The repository maintains informations about class interdependencies, e.g.,
    - * whether a class is a sub-class of another. Delegates actual class loading
    - * to SyntheticRepository with current class path by default.
    + * The repository maintains informations about class interdependencies, e.g., whether a class is a sub-class of another.
    + * Delegates actual class loading to SyntheticRepository with current class path by default.
      *
      * @see com.sun.org.apache.bcel.internal.util.Repository
      * @see SyntheticRepository
      *
    - * @LastModified: Jan 2020
    + * @LastModified: Feb 2023
      */
     public abstract class Repository {
     
    -    private static com.sun.org.apache.bcel.internal.util.Repository repository
    -            = SyntheticRepository.getInstance();
    -
    +    private static com.sun.org.apache.bcel.internal.util.Repository repository = SyntheticRepository.getInstance();
     
         /**
    -     * @return currently used repository instance
    +     * Adds clazz to repository if there isn't an equally named class already in there.
    +     *
    +     * @return old entry in repository
          */
    -    public static com.sun.org.apache.bcel.internal.util.Repository getRepository() {
    -        return repository;
    +    public static JavaClass addClass(final JavaClass clazz) {
    +        final JavaClass old = repository.findClass(clazz.getClassName());
    +        repository.storeClass(clazz);
    +        return old;
         }
     
    -
         /**
    -     * Sets repository instance to be used for class loading
    +     * Clears the repository.
          */
    -    public static void setRepository( final com.sun.org.apache.bcel.internal.util.Repository rep ) {
    -        repository = rep;
    +    public static void clearCache() {
    +        repository.clear();
         }
     
    -
         /**
    -     * Lookups class somewhere found on your CLASSPATH, or whereever the
    -     * repository instance looks for it.
    -     *
    -     * @return class object for given fully qualified class name
    -     * @throws ClassNotFoundException if the class could not be found or
    -     * parsed correctly
    +     * @return all interfaces implemented by class and its super classes and the interfaces that those interfaces extend,
    +     *         and so on. (Some people call this a transitive hull).
    +     * @throws ClassNotFoundException if any of the class's superclasses or superinterfaces can't be found
          */
    -    public static JavaClass lookupClass( final String class_name ) throws ClassNotFoundException {
    -        return repository.loadClass(class_name);
    +    public static JavaClass[] getInterfaces(final JavaClass clazz) throws ClassNotFoundException {
    +        return clazz.getAllInterfaces();
         }
     
    -
         /**
    -     * Tries to find class source using the internal repository instance.
    -     *
    -     * @see Class
    -     * @return JavaClass object for given runtime class
    -     * @throws ClassNotFoundException if the class could not be found or
    -     * parsed correctly
    +     * @return all interfaces implemented by class and its super classes and the interfaces that extend those interfaces,
    +     *         and so on
    +     * @throws ClassNotFoundException if the named class can't be found, or if any of its superclasses or superinterfaces
    +     *         can't be found
          */
    -    public static JavaClass lookupClass( final Class clazz ) throws ClassNotFoundException {
    -        return repository.loadClass(clazz);
    +    public static JavaClass[] getInterfaces(final String className) throws ClassNotFoundException {
    +        return getInterfaces(lookupClass(className));
         }
     
    -
         /**
    -     * Clear the repository.
    +     * @return currently used repository instance
          */
    -    public static void clearCache() {
    -        repository.clear();
    +    public static com.sun.org.apache.bcel.internal.util.Repository getRepository() {
    +        return repository;
         }
     
    -
         /**
    -     * Adds clazz to repository if there isn't an equally named class already in there.
    -     *
    -     * @return old entry in repository
    +     * @return list of super classes of clazz in ascending order, i.e., Object is always the last element
    +     * @throws ClassNotFoundException if any of the superclasses can't be found
          */
    -    public static JavaClass addClass( final JavaClass clazz ) {
    -        final JavaClass old = repository.findClass(clazz.getClassName());
    -        repository.storeClass(clazz);
    -        return old;
    +    public static JavaClass[] getSuperClasses(final JavaClass clazz) throws ClassNotFoundException {
    +        return clazz.getSuperClasses();
         }
     
    -
         /**
    -     * Removes class with given (fully qualified) name from repository.
    +     * @return list of super classes of clazz in ascending order, i.e., Object is always the last element.
    +     * @throws ClassNotFoundException if the named class or any of its superclasses can't be found
          */
    -    public static void removeClass( final String clazz ) {
    -        repository.removeClass(repository.findClass(clazz));
    +    public static JavaClass[] getSuperClasses(final String className) throws ClassNotFoundException {
    +        return getSuperClasses(lookupClass(className));
         }
     
    -
         /**
    -     * Removes given class from repository.
    +     * @return true, if clazz is an implementation of interface inter
    +     * @throws ClassNotFoundException if any superclasses or superinterfaces of clazz can't be found
          */
    -    public static void removeClass( final JavaClass clazz ) {
    -        repository.removeClass(clazz);
    +    public static boolean implementationOf(final JavaClass clazz, final JavaClass inter) throws ClassNotFoundException {
    +        return clazz.implementationOf(inter);
         }
     
    -
         /**
    -     * @return list of super classes of clazz in ascending order, i.e.,
    -     * Object is always the last element
    -     * @throws ClassNotFoundException if any of the superclasses can't be found
    +     * @return true, if clazz is an implementation of interface inter
    +     * @throws ClassNotFoundException if inter or any superclasses or superinterfaces of clazz can't be found
          */
    -    public static JavaClass[] getSuperClasses( final JavaClass clazz ) throws ClassNotFoundException {
    -        return clazz.getSuperClasses();
    +    public static boolean implementationOf(final JavaClass clazz, final String inter) throws ClassNotFoundException {
    +        return implementationOf(clazz, lookupClass(inter));
         }
     
    -
         /**
    -     * @return list of super classes of clazz in ascending order, i.e.,
    -     * Object is always the last element.
    -     * @throws ClassNotFoundException if the named class or any of its
    -     *  superclasses can't be found
    +     * @return true, if clazz is an implementation of interface inter
    +     * @throws ClassNotFoundException if clazz or any superclasses or superinterfaces of clazz can't be found
          */
    -    public static JavaClass[] getSuperClasses( final String class_name ) throws ClassNotFoundException {
    -        final JavaClass jc = lookupClass(class_name);
    -        return getSuperClasses(jc);
    +    public static boolean implementationOf(final String clazz, final JavaClass inter) throws ClassNotFoundException {
    +        return implementationOf(lookupClass(clazz), inter);
         }
     
    -
         /**
    -     * @return all interfaces implemented by class and its super
    -     * classes and the interfaces that those interfaces extend, and so on.
    -     * (Some people call this a transitive hull).
    -     * @throws ClassNotFoundException if any of the class's
    -     *  superclasses or superinterfaces can't be found
    +     * @return true, if clazz is an implementation of interface inter
    +     * @throws ClassNotFoundException if clazz, inter, or any superclasses or superinterfaces of clazz can't be found
          */
    -    public static JavaClass[] getInterfaces( final JavaClass clazz ) throws ClassNotFoundException {
    -        return clazz.getAllInterfaces();
    +    public static boolean implementationOf(final String clazz, final String inter) throws ClassNotFoundException {
    +        return implementationOf(lookupClass(clazz), lookupClass(inter));
         }
     
    -
         /**
    -     * @return all interfaces implemented by class and its super
    -     * classes and the interfaces that extend those interfaces, and so on
    -     * @throws ClassNotFoundException if the named class can't be found,
    -     *   or if any of its superclasses or superinterfaces can't be found
    +     * Equivalent to runtime "instanceof" operator.
    +     *
    +     * @return true, if clazz is an instance of superclass
    +     * @throws ClassNotFoundException if any superclasses or superinterfaces of clazz can't be found
          */
    -    public static JavaClass[] getInterfaces( final String class_name ) throws ClassNotFoundException {
    -        return getInterfaces(lookupClass(class_name));
    +    public static boolean instanceOf(final JavaClass clazz, final JavaClass superclass) throws ClassNotFoundException {
    +        return clazz.instanceOf(superclass);
         }
     
    -
         /**
    -     * Equivalent to runtime "instanceof" operator.
    -     * @return true, if clazz is an instance of super_class
    -     * @throws ClassNotFoundException if any superclasses or superinterfaces
    -     *   of clazz can't be found
    +     * @return true, if clazz is an instance of superclass
    +     * @throws ClassNotFoundException if superclass can't be found
          */
    -    public static boolean instanceOf( final JavaClass clazz, final JavaClass super_class )
    -            throws ClassNotFoundException {
    -        return clazz.instanceOf(super_class);
    +    public static boolean instanceOf(final JavaClass clazz, final String superclass) throws ClassNotFoundException {
    +        return instanceOf(clazz, lookupClass(superclass));
         }
     
    -
         /**
    -     * @return true, if clazz is an instance of super_class
    -     * @throws ClassNotFoundException if either clazz or super_class
    -     *   can't be found
    +     * @return true, if clazz is an instance of superclass
    +     * @throws ClassNotFoundException if clazz can't be found
          */
    -    public static boolean instanceOf( final String clazz, final String super_class )
    -            throws ClassNotFoundException {
    -        return instanceOf(lookupClass(clazz), lookupClass(super_class));
    +    public static boolean instanceOf(final String clazz, final JavaClass superclass) throws ClassNotFoundException {
    +        return instanceOf(lookupClass(clazz), superclass);
         }
     
    -
         /**
    -     * @return true, if clazz is an instance of super_class
    -     * @throws ClassNotFoundException if super_class can't be found
    +     * @return true, if clazz is an instance of superclass
    +     * @throws ClassNotFoundException if either clazz or superclass can't be found
          */
    -    public static boolean instanceOf( final JavaClass clazz, final String super_class )
    -            throws ClassNotFoundException {
    -        return instanceOf(clazz, lookupClass(super_class));
    +    public static boolean instanceOf(final String clazz, final String superclass) throws ClassNotFoundException {
    +        return instanceOf(lookupClass(clazz), lookupClass(superclass));
         }
     
    -
         /**
    -     * @return true, if clazz is an instance of super_class
    -     * @throws ClassNotFoundException if clazz can't be found
    +     * Tries to find class source using the internal repository instance.
    +     *
    +     * @see Class
    +     * @return JavaClass object for given runtime class
    +     * @throws ClassNotFoundException if the class could not be found or parsed correctly
          */
    -    public static boolean instanceOf( final String clazz, final JavaClass super_class )
    -            throws ClassNotFoundException {
    -        return instanceOf(lookupClass(clazz), super_class);
    +    public static JavaClass lookupClass(final Class clazz) throws ClassNotFoundException {
    +        return repository.loadClass(clazz);
         }
     
    -
         /**
    -     * @return true, if clazz is an implementation of interface inter
    -     * @throws ClassNotFoundException if any superclasses or superinterfaces
    -     *   of clazz can't be found
    +     * Lookups class somewhere found on your CLASSPATH, or wherever the repository instance looks for it.
    +     *
    +     * @return class object for given fully qualified class name
    +     * @throws ClassNotFoundException if the class could not be found or parsed correctly
          */
    -    public static boolean implementationOf( final JavaClass clazz, final JavaClass inter )
    -            throws ClassNotFoundException {
    -        return clazz.implementationOf(inter);
    +    public static JavaClass lookupClass(final String className) throws ClassNotFoundException {
    +        return repository.loadClass(className);
         }
     
    -
         /**
    -     * @return true, if clazz is an implementation of interface inter
    -     * @throws ClassNotFoundException if clazz, inter, or any superclasses
    -     *   or superinterfaces of clazz can't be found
    +     * Removes given class from repository.
          */
    -    public static boolean implementationOf( final String clazz, final String inter )
    -            throws ClassNotFoundException {
    -        return implementationOf(lookupClass(clazz), lookupClass(inter));
    +    public static void removeClass(final JavaClass clazz) {
    +        repository.removeClass(clazz);
         }
     
    -
         /**
    -     * @return true, if clazz is an implementation of interface inter
    -     * @throws ClassNotFoundException if inter or any superclasses
    -     *   or superinterfaces of clazz can't be found
    +     * Removes class with given (fully qualified) name from repository.
          */
    -    public static boolean implementationOf( final JavaClass clazz, final String inter )
    -            throws ClassNotFoundException {
    -        return implementationOf(clazz, lookupClass(inter));
    +    public static void removeClass(final String clazz) {
    +        repository.removeClass(repository.findClass(clazz));
         }
     
    -
         /**
    -     * @return true, if clazz is an implementation of interface inter
    -     * @throws ClassNotFoundException if clazz or any superclasses or
    -     *   superinterfaces of clazz can't be found
    +     * Sets repository instance to be used for class loading
          */
    -    public static boolean implementationOf( final String clazz, final JavaClass inter )
    -            throws ClassNotFoundException {
    -        return implementationOf(lookupClass(clazz), inter);
    +    public static void setRepository(final com.sun.org.apache.bcel.internal.util.Repository rep) {
    +        repository = rep;
         }
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Args.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Args.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Args.java	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Args.java	2023-10-06 05:33:33.000000000 +0000
    @@ -0,0 +1,148 @@
    +/*
    + * reserved comment block
    + * DO NOT REMOVE OR ALTER!
    + */
    +/*
    + * 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.
    + */
    +
    +package com.sun.org.apache.bcel.internal.util;
    +
    +import com.sun.org.apache.bcel.internal.Const;
    +import com.sun.org.apache.bcel.internal.classfile.ClassFormatException;
    +
    +/**
    + * Argument validation.
    + *
    + * @since 6.7.0
    + */
    +public class Args {
    +
    +    /**
    +     * Requires a specific value.
    +     *
    +     * @param value    The value to test.
    +     * @param required The required value.
    +     * @param message  The message prefix
    +     * @return The value to test.
    +     */
    +    public static int require(final int value, final int required, final String message) {
    +        if (value != required) {
    +            throw new ClassFormatException(String.format("%s [Value must be 0: %,d]", message, value));
    +        }
    +        return value;
    +    }
    +
    +    /**
    +     * Requires a 0 value.
    +     *
    +     * @param value   The value to test.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int require0(final int value, final String message) {
    +        return require(value, 0, message);
    +    }
    +
    +    /**
    +     * Requires a u1 value.
    +     *
    +     * @param value   The value to test.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int requireU1(final int value, final String message) {
    +        if (value < 0 || value > Const.MAX_BYTE) {
    +            throw new ClassFormatException(String.format("%s [Value out of range (0 - %,d) for type u1: %,d]", message, Const.MAX_BYTE, value));
    +        }
    +        return value;
    +    }
    +
    +    /**
    +     * Requires a u2 value of at least {@code min} and not above {@code max}.
    +     *
    +     * @param value   The value to test.
    +     * @param min     The minimum required u2 value.
    +     * @param max     The maximum required u2 value.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int requireU2(final int value, final int min, final int max, final String message) {
    +        if (max > Const.MAX_SHORT) {
    +            throw new IllegalArgumentException(String.format("%s programming error: max %,d > %,d", message, max, Const.MAX_SHORT));
    +        }
    +        if (min < 0) {
    +            throw new IllegalArgumentException(String.format("%s programming error: min %,d < 0", message, min));
    +        }
    +        if (value < min || value > max) {
    +            throw new ClassFormatException(String.format("%s [Value out of range (%,d - %,d) for type u2: %,d]", message, min, Const.MAX_SHORT, value));
    +        }
    +        return value;
    +    }
    +
    +    /**
    +     * Requires a u2 value of at least {@code min}.
    +     *
    +     * @param value   The value to test.
    +     * @param min     The minimum required value.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int requireU2(final int value, final int min, final String message) {
    +        return requireU2(value, min, Const.MAX_SHORT, message);
    +    }
    +
    +    /**
    +     * Requires a u2 value.
    +     *
    +     * @param value   The value to test.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int requireU2(final int value, final String message) {
    +        return requireU2(value, 0, message);
    +    }
    +
    +    /**
    +     * Requires a u4 value of at least {@code min}.
    +     *
    +     * @param value   The value to test.
    +     * @param min     The minimum required value.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int requireU4(final int value, final int min, final String message) {
    +        if (min < 0) {
    +            throw new IllegalArgumentException(String.format("%s programming error: min %,d < 0", message, min));
    +        }
    +        if (value < min) {
    +            throw new ClassFormatException(
    +                    String.format("%s [Value out of range (%,d - %,d) for type u2: %,d]", message, min, Integer.MAX_VALUE, value & 0xFFFFFFFFL));
    +        }
    +        return value;
    +    }
    +
    +    /**
    +     * Requires a u4 value.
    +     *
    +     * @param value   The value to test.
    +     * @param message The message prefix
    +     * @return The value to test.
    +     */
    +    public static int requireU4(final int value, final String message) {
    +        return requireU4(value, 0, message);
    +    }
    +}
    diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java
    --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/AttributeHTML.java	2023-10-06 05:33:33.000000000 +0000
    @@ -21,196 +21,175 @@
     
     package com.sun.org.apache.bcel.internal.util;
     
    -import java.io.FileOutputStream;
    -import java.io.IOException;
    +import java.io.Closeable;
    +import java.io.FileNotFoundException;
     import java.io.PrintWriter;
    +import java.io.UnsupportedEncodingException;
    +import java.nio.charset.Charset;
     
     import com.sun.org.apache.bcel.internal.Const;
     import com.sun.org.apache.bcel.internal.classfile.Attribute;
     import com.sun.org.apache.bcel.internal.classfile.Code;
     import com.sun.org.apache.bcel.internal.classfile.CodeException;
     import com.sun.org.apache.bcel.internal.classfile.ConstantPool;
    -import com.sun.org.apache.bcel.internal.classfile.ConstantUtf8;
     import com.sun.org.apache.bcel.internal.classfile.ConstantValue;
     import com.sun.org.apache.bcel.internal.classfile.ExceptionTable;
     import com.sun.org.apache.bcel.internal.classfile.InnerClass;
     import com.sun.org.apache.bcel.internal.classfile.InnerClasses;
     import com.sun.org.apache.bcel.internal.classfile.LineNumber;
     import com.sun.org.apache.bcel.internal.classfile.LineNumberTable;
    -import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
     import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable;
     import com.sun.org.apache.bcel.internal.classfile.SourceFile;
     import com.sun.org.apache.bcel.internal.classfile.Utility;
     
     /**
      * Convert found attributes into HTML file.
    - *
    - *
      */
    -final class AttributeHTML {
    +final class AttributeHTML implements Closeable {
     
    -    private final String class_name; // name of current class
    -    private final PrintWriter file; // file to write to
    -    private int attr_count = 0;
    -    private final ConstantHTML constant_html;
    -    private final ConstantPool constant_pool;
    -
    -
    -    AttributeHTML(final String dir, final String class_name, final ConstantPool constant_pool,
    -            final ConstantHTML constant_html) throws IOException {
    -        this.class_name = class_name;
    -        this.constant_pool = constant_pool;
    -        this.constant_html = constant_html;
    -        file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html"));
    -        file.println("");
    +    private final String className; // name of current class
    +    private final PrintWriter printWriter; // file to write to
    +    private int attrCount;
    +    private final ConstantHTML constantHtml;
    +    private final ConstantPool constantPool;
    +
    +    AttributeHTML(final String dir, final String className, final ConstantPool constantPool, final ConstantHTML constantHtml, final Charset charset)
    +        throws FileNotFoundException, UnsupportedEncodingException {
    +        this.className = className;
    +        this.constantPool = constantPool;
    +        this.constantHtml = constantHtml;
    +        printWriter = new PrintWriter(dir + className + "_attributes.html", charset.name());
    +        printWriter.print("");
    +        printWriter.println("
    "); } - - private String codeLink( final int link, final int method_number ) { - return "" + link + ""; + @Override + public void close() { + printWriter.println("
    "); + printWriter.close(); } - - void close() { - file.println(""); - file.close(); + private String codeLink(final int link, final int methodNumber) { + return "" + link + ""; } - - void writeAttribute( final Attribute attribute, final String anchor ) { + void writeAttribute(final Attribute attribute, final String anchor) { writeAttribute(attribute, anchor, 0); } - - void writeAttribute( final Attribute attribute, final String anchor, final int method_number ) { + void writeAttribute(final Attribute attribute, final String anchor, final int methodNumber) { final byte tag = attribute.getTag(); int index; if (tag == Const.ATTR_UNKNOWN) { return; } - attr_count++; // Increment number of attributes found so far - if (attr_count % 2 == 0) { - file.print(""); + attrCount++; // Increment number of attributes found so far + if (attrCount % 2 == 0) { + printWriter.print(""); } else { - file.print(""); + printWriter.print(""); } - file.println("

    " + attr_count + " " + Const.getAttributeName(tag) - + "

    "); - /* Handle different attributes + printWriter.println("

    " + attrCount + " " + Const.getAttributeName(tag) + "

    "); + /* + * Handle different attributes */ switch (tag) { - case Const.ATTR_CODE: - final Code c = (Code) attribute; - // Some directly printable values - file.print("
    • Maximum stack size = " + c.getMaxStack() - + "
    • \n
    • Number of local variables = " + c.getMaxLocals() - + "
    • \n
    • Byte code
    \n"); - // Get handled exceptions and list them - final CodeException[] ce = c.getExceptionTable(); - final int len = ce.length; - if (len > 0) { - file.print("

    Exceptions handled

      "); - for (final CodeException cex : ce) { - final int catch_type = cex.getCatchType(); // Index in constant pool - file.print("
    • "); - if (catch_type != 0) { - file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html - } else { - file.print("Any Exception"); - } - file.print("
      (Ranging from lines " - + codeLink(cex.getStartPC(), method_number) + " to " - + codeLink(cex.getEndPC(), method_number) + ", handled at line " - + codeLink(cex.getHandlerPC(), method_number) + ")
    • "); - } - file.print("
    "); - } - break; - case Const.ATTR_CONSTANT_VALUE: - index = ((ConstantValue) attribute).getConstantValueIndex(); - // Reference _cp.html - file.print("\n"); - break; - case Const.ATTR_SOURCE_FILE: - index = ((SourceFile) attribute).getSourceFileIndex(); - // Reference _cp.html - file.print("\n"); - break; - case Const.ATTR_EXCEPTIONS: - // List thrown exceptions - final int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable(); - file.print("\n"); - break; - case Const.ATTR_LINE_NUMBER_TABLE: - final LineNumber[] line_numbers = ((LineNumberTable) attribute).getLineNumberTable(); - // List line number pairs - file.print("

    "); - for (int i = 0; i < line_numbers.length; i++) { - file.print("(" + line_numbers[i].getStartPC() + ", " - + line_numbers[i].getLineNumber() + ")"); - if (i < line_numbers.length - 1) { - file.print(", "); // breakable + case Const.ATTR_CODE: + final Code c = (Code) attribute; + // Some directly printable values + printWriter.print("

    • Maximum stack size = " + c.getMaxStack() + "
    • \n
    • Number of local variables = " + c.getMaxLocals() + + "
    • \n
    • Byte code
    \n"); + // Get handled exceptions and list them + final CodeException[] ce = c.getExceptionTable(); + final int len = ce.length; + if (len > 0) { + printWriter.print("

    Exceptions handled

      "); + for (final CodeException cex : ce) { + final int catchType = cex.getCatchType(); // Index in constant pool + printWriter.print("
    • "); + if (catchType != 0) { + printWriter.print(constantHtml.referenceConstant(catchType)); // Create Link to _cp.html + } else { + printWriter.print("Any Exception"); } + printWriter.print("
      (Ranging from lines " + codeLink(cex.getStartPC(), methodNumber) + " to " + codeLink(cex.getEndPC(), methodNumber) + + ", handled at line " + codeLink(cex.getHandlerPC(), methodNumber) + ")
    • "); } - break; - case Const.ATTR_LOCAL_VARIABLE_TABLE: - final LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable(); - // List name, range and type - file.print("
        "); - for (final LocalVariable var : vars) { - index = var.getSignatureIndex(); - String signature = ((ConstantUtf8) constant_pool.getConstant(index, - Const.CONSTANT_Utf8)).getBytes(); - signature = Utility.signatureToString(signature, false); - final int start = var.getStartPC(); - final int end = start + var.getLength(); - file.println("
      • " + Class2HTML.referenceType(signature) + " " - + var.getName() + " in slot %" + var.getIndex() - + "
        Valid from lines " + "" - + start + " to " + "" + end + "
      • "); + printWriter.print("
      "); + } + break; + case Const.ATTR_CONSTANT_VALUE: + index = ((ConstantValue) attribute).getConstantValueIndex(); + // Reference _cp.html + printWriter + .print("\n"); + break; + case Const.ATTR_SOURCE_FILE: + index = ((SourceFile) attribute).getSourceFileIndex(); + // Reference _cp.html + printWriter + .print("\n"); + break; + case Const.ATTR_EXCEPTIONS: + // List thrown exceptions + final int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable(); + printWriter.print("\n"); + break; + case Const.ATTR_LINE_NUMBER_TABLE: + final LineNumber[] lineNumbers = ((LineNumberTable) attribute).getLineNumberTable(); + // List line number pairs + printWriter.print("

      "); + for (int i = 0; i < lineNumbers.length; i++) { + printWriter.print("(" + lineNumbers[i].getStartPC() + ", " + lineNumbers[i].getLineNumber() + ")"); + if (i < lineNumbers.length - 1) { + printWriter.print(", "); // breakable } - file.print("

    \n"); - break; - case Const.ATTR_INNER_CLASSES: - final InnerClass[] classes = ((InnerClasses) attribute).getInnerClasses(); - // List inner classes - file.print("
      "); - for (final InnerClass classe : classes) { - String name; - String access; - index = classe.getInnerNameIndex(); - if (index > 0) { - name = ((ConstantUtf8) constant_pool.getConstant(index, Const.CONSTANT_Utf8)) - .getBytes(); - } else { - name = "<anonymous>"; - } - access = Utility.accessToString(classe.getInnerAccessFlags()); - file.print("
    • " + access + " " - + constant_html.referenceConstant(classe.getInnerClassIndex()) - + " in class " - + constant_html.referenceConstant(classe.getOuterClassIndex()) - + " named " + name + "
    • \n"); + } + break; + case Const.ATTR_LOCAL_VARIABLE_TABLE: + // List name, range and type + printWriter.print("
        "); + ((LocalVariableTable) attribute).forEach(var -> { + final int sigIdx = var.getSignatureIndex(); + String signature = constantPool.getConstantUtf8(sigIdx).getBytes(); + signature = Utility.signatureToString(signature, false); + final int start = var.getStartPC(); + final int end = start + var.getLength(); + printWriter.println("
      • " + Class2HTML.referenceType(signature) + " " + var.getName() + " in slot %" + var.getIndex() + + "
        Valid from lines " + "" + start + + " to " + "" + end + "
      • "); + }); + printWriter.print("
      \n"); + break; + case Const.ATTR_INNER_CLASSES: + // List inner classes + printWriter.print("
        "); + for (final InnerClass clazz : ((InnerClasses) attribute).getInnerClasses()) { + final String name; + final String access; + index = clazz.getInnerNameIndex(); + if (index > 0) { + name = constantPool.getConstantUtf8(index).getBytes(); + } else { + name = "<anonymous>"; } - file.print("
      \n"); - break; - default: // Such as Unknown attribute or Deprecated - file.print("

      " + attribute); + access = Utility.accessToString(clazz.getInnerAccessFlags()); + printWriter.print("

    • " + access + " " + constantHtml.referenceConstant(clazz.getInnerClassIndex()) + + " in class " + constantHtml.referenceConstant(clazz.getOuterClassIndex()) + " named " + name + "
    • \n"); + } + printWriter.print("
    \n"); + break; + default: // Such as Unknown attribute or Deprecated + printWriter.print("

    " + attribute); } - file.println(""); - file.flush(); + printWriter.println(""); + printWriter.flush(); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELComparator.java 2023-10-06 05:33:33.000000000 +0000 @@ -35,8 +35,7 @@ * @param THAT * @return true if and only if THIS equals THAT */ - boolean equals( Object THIS, Object THAT ); - + boolean equals(Object THIS, Object THAT); /** * Return hashcode for THIS.hashCode() @@ -44,5 +43,5 @@ * @param THIS * @return hashcode for THIS.hashCode() */ - int hashCode( Object THIS ); + int hashCode(Object THIS); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELFactory.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -60,45 +60,85 @@ import com.sun.org.apache.bcel.internal.generic.Type; /** - * Factory creates il.append() statements, and sets instruction targets. - * A helper class for BCELifier. + * Factory creates il.append() statements, and sets instruction targets. A helper class for BCELifier. * * @see BCELifier - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ class BCELFactory extends EmptyVisitor { - private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+"."; - private final MethodGen _mg; - private final PrintWriter _out; - private final ConstantPoolGen _cp; + private static final String CONSTANT_PREFIX = Const.class.getSimpleName() + "."; + private final MethodGen methodGen; + private final PrintWriter printWriter; + private final ConstantPoolGen constantPoolGen; + private final Map branchMap = new HashMap<>(); + + // Memorize BranchInstructions that need an update + private final List branches = new ArrayList<>(); BCELFactory(final MethodGen mg, final PrintWriter out) { - _mg = mg; - _cp = mg.getConstantPool(); - _out = out; + methodGen = mg; + constantPoolGen = mg.getConstantPool(); + printWriter = out; } - private final Map branch_map = new HashMap<>(); + private void createConstant(final Object value) { + String embed = value.toString(); + if (value instanceof String) { + embed = '"' + Utility.convertString(embed) + '"'; + } else if (value instanceof Character) { + embed = "(char)0x" + Integer.toHexString(((Character) value).charValue()); + } else if (value instanceof Float) { + final Float f = (Float) value; + if (Float.isNaN(f)) { + embed = "Float.NaN"; + } else if (f == Float.POSITIVE_INFINITY) { + embed = "Float.POSITIVE_INFINITY"; + } else if (f == Float.NEGATIVE_INFINITY) { + embed = "Float.NEGATIVE_INFINITY"; + } else { + embed += "f"; + } + } else if (value instanceof Double) { + final Double d = (Double) value; + if (Double.isNaN(d)) { + embed = "Double.NaN"; + } else if (d == Double.POSITIVE_INFINITY) { + embed = "Double.POSITIVE_INFINITY"; + } else if (d == Double.NEGATIVE_INFINITY) { + embed = "Double.NEGATIVE_INFINITY"; + } else { + embed += "d"; + } + } else if (value instanceof Long) { + embed += "L"; + } else if (value instanceof ObjectType) { + final ObjectType ot = (ObjectType) value; + embed = "new ObjectType(\"" + ot.getClassName() + "\")"; + } else if (value instanceof ArrayType) { + final ArrayType at = (ArrayType) value; + embed = "new ArrayType(" + BCELifier.printType(at.getBasicType()) + ", " + at.getDimensions() + ")"; + } + printWriter.println("il.append(new PUSH(_cp, " + embed + "));"); + } public void start() { - if (!_mg.isAbstract() && !_mg.isNative()) { - for (InstructionHandle ih = _mg.getInstructionList().getStart(); ih != null; ih = ih - .getNext()) { + if (!methodGen.isAbstract() && !methodGen.isNative()) { + for (InstructionHandle ih = methodGen.getInstructionList().getStart(); ih != null; ih = ih.getNext()) { final Instruction i = ih.getInstruction(); if (i instanceof BranchInstruction) { - branch_map.put(i, ih); // memorize container + branchMap.put(i, ih); // memorize container } if (ih.hasTargeters()) { if (i instanceof BranchInstruction) { - _out.println(" InstructionHandle ih_" + ih.getPosition() + ";"); + printWriter.println(" InstructionHandle ih_" + ih.getPosition() + ";"); } else { - _out.print(" InstructionHandle ih_" + ih.getPosition() + " = "); + printWriter.print(" InstructionHandle ih_" + ih.getPosition() + " = "); } } else { - _out.print(" "); + printWriter.print(" "); } if (!visitInstruction(i)) { i.accept(this); @@ -109,167 +149,74 @@ } } - - private boolean visitInstruction( final Instruction i ) { - final short opcode = i.getOpcode(); - if ((InstructionConst.getInstruction(opcode) != null) - && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { // Handled below - _out.println("il.append(InstructionConst." - + i.getName().toUpperCase(Locale.ENGLISH) + ");"); - return true; - } - return false; + private void updateBranchTargets() { + branches.forEach(bi -> { + final BranchHandle bh = (BranchHandle) branchMap.get(bi); + final int pos = bh.getPosition(); + final String name = bi.getName() + "_" + pos; + int targetPos = bh.getTarget().getPosition(); + printWriter.println(" " + name + ".setTarget(ih_" + targetPos + ");"); + if (bi instanceof Select) { + final InstructionHandle[] ihs = ((Select) bi).getTargets(); + for (int j = 0; j < ihs.length; j++) { + targetPos = ihs[j].getPosition(); + printWriter.println(" " + name + ".setTarget(" + j + ", ih_" + targetPos + ");"); + } + } + }); } - - @Override - public void visitLocalVariableInstruction( final LocalVariableInstruction i ) { - final short opcode = i.getOpcode(); - final Type type = i.getType(_cp); - if (opcode == Const.IINC) { - _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() - + "));"); - } else { - final String kind = (opcode < Const.ISTORE) ? "Load" : "Store"; - _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) - + ", " + i.getIndex() + "));"); + private void updateExceptionHandlers() { + final CodeExceptionGen[] handlers = methodGen.getExceptionHandlers(); + for (final CodeExceptionGen h : handlers) { + final String type = h.getCatchType() == null ? "null" : BCELifier.printType(h.getCatchType()); + printWriter.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() + ", " + "ih_" + h.getEndPC().getPosition() + ", " + + "ih_" + h.getHandlerPC().getPosition() + ", " + type + ");"); } } - - @Override - public void visitArrayInstruction( final ArrayInstruction i ) { - final short opcode = i.getOpcode(); - final Type type = i.getType(_cp); - final String kind = (opcode < Const.IASTORE) ? "Load" : "Store"; - _out.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type) - + "));"); - } - - - @Override - public void visitFieldInstruction( final FieldInstruction i ) { - final short opcode = i.getOpcode(); - final String class_name = i.getReferenceType(_cp).getSignature(); - final String field_name = i.getFieldName(_cp); - final Type type = i.getFieldType(_cp); - _out.println("il.append(_factory.createFieldAccess(\"" + class_name + "\", \"" + field_name - + "\", " + BCELifier.printType(type) + ", " + CONSTANT_PREFIX - + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); - } - - - @Override - public void visitInvokeInstruction( final InvokeInstruction i ) { - final short opcode = i.getOpcode(); - final String class_name = i.getReferenceType(_cp).getSignature(); - final String method_name = i.getMethodName(_cp); - final Type type = i.getReturnType(_cp); - final Type[] arg_types = i.getArgumentTypes(_cp); - _out.println("il.append(_factory.createInvoke(\"" + class_name + "\", \"" + method_name - + "\", " + BCELifier.printType(type) + ", " - + BCELifier.printArgumentTypes(arg_types) + ", " + CONSTANT_PREFIX - + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); - } - - @Override @SuppressWarnings("fallthrough") // by design for case Const.ANEWARRAY - public void visitAllocationInstruction( final AllocationInstruction i ) { + public void visitAllocationInstruction(final AllocationInstruction i) { Type type; if (i instanceof CPInstruction) { - type = ((CPInstruction) i).getType(_cp); + type = ((CPInstruction) i).getType(constantPoolGen); } else { type = ((NEWARRAY) i).getType(); } final short opcode = ((Instruction) i).getOpcode(); int dim = 1; switch (opcode) { - case Const.NEW: - _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() - + "\"));"); - break; - case Const.MULTIANEWARRAY: - dim = ((MULTIANEWARRAY) i).getDimensions(); - //$FALL-THROUGH$ - case Const.ANEWARRAY: - case Const.NEWARRAY: - if (type instanceof ArrayType) { - type = ((ArrayType) type).getBasicType(); - } - _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) - + ", (short) " + dim + "));"); - break; - default: - throw new IllegalArgumentException("Unhandled opcode: " + opcode); - } - } - - - private void createConstant( final Object value ) { - String embed = value.toString(); - if (value instanceof String) { - embed = '"' + Utility.convertString(embed) + '"'; - } else if (value instanceof Character) { - embed = "(char)0x" + Integer.toHexString(((Character) value).charValue()); - } else if (value instanceof Float) { - embed += "f"; - } else if (value instanceof Long) { - embed += "L"; - } else if (value instanceof ObjectType) { - final ObjectType ot = (ObjectType) value; - embed = "new ObjectType(\""+ot.getClassName()+"\")"; + case Const.NEW: + printWriter.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName() + "\"));"); + break; + case Const.MULTIANEWARRAY: + dim = ((MULTIANEWARRAY) i).getDimensions(); + //$FALL-THROUGH$ + case Const.NEWARRAY: + if (type instanceof ArrayType) { + type = ((ArrayType) type).getBasicType(); + } + //$FALL-THROUGH$ + case Const.ANEWARRAY: + printWriter.println("il.append(_factory.createNewArray(" + BCELifier.printType(type) + ", (short) " + dim + "));"); + break; + default: + throw new IllegalArgumentException("Unhandled opcode: " + opcode); } - - _out.println("il.append(new PUSH(_cp, " + embed + "));"); - } - - - @Override - public void visitLDC( final LDC i ) { - createConstant(i.getValue(_cp)); - } - - - @Override - public void visitLDC2_W( final LDC2_W i ) { - createConstant(i.getValue(_cp)); } - @Override - public void visitConstantPushInstruction( final ConstantPushInstruction i ) { - createConstant(i.getValue()); - } - - - @Override - public void visitINSTANCEOF( final INSTANCEOF i ) { - final Type type = i.getType(_cp); - _out.println("il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));"); - } - - - @Override - public void visitCHECKCAST( final CHECKCAST i ) { - final Type type = i.getType(_cp); - _out.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));"); + public void visitArrayInstruction(final ArrayInstruction i) { + final short opcode = i.getOpcode(); + final Type type = i.getType(constantPoolGen); + final String kind = opcode < Const.IASTORE ? "Load" : "Store"; + printWriter.println("il.append(_factory.createArray" + kind + "(" + BCELifier.printType(type) + "));"); } - @Override - public void visitReturnInstruction( final ReturnInstruction i ) { - final Type type = i.getType(_cp); - _out.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));"); - } - - // Memorize BranchInstructions that need an update - private final List branches = new ArrayList<>(); - - - @Override - public void visitBranchInstruction( final BranchInstruction bi ) { - final BranchHandle bh = (BranchHandle) branch_map.get(bi); + public void visitBranchInstruction(final BranchInstruction bi) { + final BranchHandle bh = (BranchHandle) branchMap.get(bi); final int pos = bh.getPosition(); final String name = bi.getName() + "_" + pos; if (bi instanceof Select) { @@ -284,68 +231,110 @@ } } args.append(" }"); - _out.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) - + "(" + args + ", new InstructionHandle[] { "); + printWriter.print("Select " + name + " = new " + bi.getName().toUpperCase(Locale.ENGLISH) + "(" + args + ", new InstructionHandle[] { "); for (int i = 0; i < matchs.length; i++) { - _out.print("null"); + printWriter.print("null"); if (i < matchs.length - 1) { - _out.print(", "); + printWriter.print(", "); } } - _out.println(" }, null);"); + printWriter.println(" }, null);"); } else { - final int t_pos = bh.getTarget().getPosition(); + final int tPos = bh.getTarget().getPosition(); String target; - if (pos > t_pos) { - target = "ih_" + t_pos; + if (pos > tPos) { + target = "ih_" + tPos; } else { branches.add(bi); target = "null"; } - _out.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" - + CONSTANT_PREFIX + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target - + ");"); + printWriter.println(" BranchInstruction " + name + " = _factory.createBranchInstruction(" + CONSTANT_PREFIX + + bi.getName().toUpperCase(Locale.ENGLISH) + ", " + target + ");"); } if (bh.hasTargeters()) { - _out.println(" ih_" + pos + " = il.append(" + name + ");"); + printWriter.println(" ih_" + pos + " = il.append(" + name + ");"); } else { - _out.println(" il.append(" + name + ");"); + printWriter.println(" il.append(" + name + ");"); } } + @Override + public void visitCHECKCAST(final CHECKCAST i) { + final Type type = i.getType(constantPoolGen); + printWriter.println("il.append(_factory.createCheckCast(" + BCELifier.printType(type) + "));"); + } + + @Override + public void visitConstantPushInstruction(final ConstantPushInstruction i) { + createConstant(i.getValue()); + } @Override - public void visitRET( final RET i ) { - _out.println("il.append(new RET(" + i.getIndex() + ")));"); + public void visitFieldInstruction(final FieldInstruction i) { + final short opcode = i.getOpcode(); + final String className = i.getReferenceType(constantPoolGen).getClassName(); + final String fieldName = i.getFieldName(constantPoolGen); + final Type type = i.getFieldType(constantPoolGen); + printWriter.println("il.append(_factory.createFieldAccess(\"" + className + "\", \"" + fieldName + "\", " + BCELifier.printType(type) + ", " + + CONSTANT_PREFIX + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); } + @Override + public void visitINSTANCEOF(final INSTANCEOF i) { + final Type type = i.getType(constantPoolGen); + printWriter.println("il.append(_factory.createInstanceOf(" + BCELifier.printType(type) + "));"); + } - private void updateBranchTargets() { - for (final BranchInstruction bi : branches) { - final BranchHandle bh = (BranchHandle) branch_map.get(bi); - final int pos = bh.getPosition(); - final String name = bi.getName() + "_" + pos; - int t_pos = bh.getTarget().getPosition(); - _out.println(" " + name + ".setTarget(ih_" + t_pos + ");"); - if (bi instanceof Select) { - final InstructionHandle[] ihs = ((Select) bi).getTargets(); - for (int j = 0; j < ihs.length; j++) { - t_pos = ihs[j].getPosition(); - _out.println(" " + name + ".setTarget(" + j + ", ih_" + t_pos + ");"); - } - } + private boolean visitInstruction(final Instruction i) { + final short opcode = i.getOpcode(); + if (InstructionConst.getInstruction(opcode) != null && !(i instanceof ConstantPushInstruction) && !(i instanceof ReturnInstruction)) { // Handled below + printWriter.println("il.append(InstructionConst." + i.getName().toUpperCase(Locale.ENGLISH) + ");"); + return true; } + return false; } + @Override + public void visitInvokeInstruction(final InvokeInstruction i) { + final short opcode = i.getOpcode(); + final String className = i.getReferenceType(constantPoolGen).getClassName(); + final String methodName = i.getMethodName(constantPoolGen); + final Type type = i.getReturnType(constantPoolGen); + final Type[] argTypes = i.getArgumentTypes(constantPoolGen); + printWriter.println("il.append(_factory.createInvoke(\"" + className + "\", \"" + methodName + "\", " + BCELifier.printType(type) + ", " + + BCELifier.printArgumentTypes(argTypes) + ", " + CONSTANT_PREFIX + Const.getOpcodeName(opcode).toUpperCase(Locale.ENGLISH) + "));"); + } - private void updateExceptionHandlers() { - final CodeExceptionGen[] handlers = _mg.getExceptionHandlers(); - for (final CodeExceptionGen h : handlers) { - final String type = (h.getCatchType() == null) ? "null" : BCELifier.printType(h - .getCatchType()); - _out.println(" method.addExceptionHandler(" + "ih_" + h.getStartPC().getPosition() - + ", " + "ih_" + h.getEndPC().getPosition() + ", " + "ih_" - + h.getHandlerPC().getPosition() + ", " + type + ");"); + @Override + public void visitLDC(final LDC i) { + createConstant(i.getValue(constantPoolGen)); + } + + @Override + public void visitLDC2_W(final LDC2_W i) { + createConstant(i.getValue(constantPoolGen)); + } + + @Override + public void visitLocalVariableInstruction(final LocalVariableInstruction i) { + final short opcode = i.getOpcode(); + final Type type = i.getType(constantPoolGen); + if (opcode == Const.IINC) { + printWriter.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() + "));"); + } else { + final String kind = opcode < Const.ISTORE ? "Load" : "Store"; + printWriter.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) + ", " + i.getIndex() + "));"); } } + + @Override + public void visitRET(final RET i) { + printWriter.println("il.append(new RET(" + i.getIndex() + "));"); + } + + @Override + public void visitReturnInstruction(final ReturnInstruction i) { + final Type type = i.getType(constantPoolGen); + printWriter.println("il.append(_factory.createReturn(" + BCELifier.printType(type) + "));"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,13 +22,16 @@ import java.io.IOException; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import java.util.Locale; import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.Repository; import com.sun.org.apache.bcel.internal.classfile.ClassParser; import com.sun.org.apache.bcel.internal.classfile.ConstantValue; +import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; import com.sun.org.apache.bcel.internal.classfile.Field; import com.sun.org.apache.bcel.internal.classfile.JavaClass; import com.sun.org.apache.bcel.internal.classfile.Method; @@ -40,12 +42,11 @@ import com.sun.org.apache.bcel.internal.generic.Type; /** - * This class takes a given JavaClass object and converts it to a - * Java program that creates that very class using BCEL. This - * gives new users of BCEL a useful example showing how things - * are done with BCEL. It does not cover all features of BCEL, - * but tries to mimic hand-written code as close as possible. + * This class takes a given JavaClass object and converts it to a Java program that creates that very class using BCEL. + * This gives new users of BCEL a useful example showing how things are done with BCEL. It does not cover all features + * of BCEL, but tries to mimic hand-written code as close as possible. * + * @LastModified: Feb 2023 */ public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor { @@ -53,186 +54,79 @@ * Enum corresponding to flag source. */ public enum FLAGS { - UNKNOWN, - CLASS, - METHOD, + UNKNOWN, CLASS, METHOD, } // The base package name for imports; assumes Const is at the top level // N.B we use the class so renames will be detected by the compiler/IDE private static final String BASE_PACKAGE = Const.class.getPackage().getName(); - private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+"."; + private static final String CONSTANT_PREFIX = Const.class.getSimpleName() + "."; - private final JavaClass _clazz; - private final PrintWriter _out; - private final ConstantPoolGen _cp; - - /** @param clazz Java class to "decompile" - * @param out where to output Java program - */ - public BCELifier(final JavaClass clazz, final OutputStream out) { - _clazz = clazz; - _out = new PrintWriter(out); - _cp = new ConstantPoolGen(_clazz.getConstantPool()); + // Needs to be accessible from unit test code + static JavaClass getJavaClass(final String name) throws ClassNotFoundException, IOException { + JavaClass javaClass; + if ((javaClass = Repository.lookupClass(name)) == null) { + javaClass = new ClassParser(name).parse(); // May throw IOException + } + return javaClass; } - - /** Start Java code generation + /** + * Default main method */ - public void start() { - visitJavaClass(_clazz); - _out.flush(); - } - - - @Override - public void visitJavaClass( final JavaClass clazz ) { - String class_name = clazz.getClassName(); - final String super_name = clazz.getSuperclassName(); - final String package_name = clazz.getPackageName(); - final String inter = Utility.printArray(clazz.getInterfaceNames(), false, true); - if (!"".equals(package_name)) { - class_name = class_name.substring(package_name.length() + 1); - _out.println("package " + package_name + ";"); - _out.println(); - } - _out.println("import " + BASE_PACKAGE + ".generic.*;"); - _out.println("import " + BASE_PACKAGE + ".classfile.*;"); - _out.println("import " + BASE_PACKAGE + ".*;"); - _out.println("import java.io.*;"); - _out.println(); - _out.println("public class " + class_name + "Creator {"); - _out.println(" private InstructionFactory _factory;"); - _out.println(" private ConstantPoolGen _cp;"); - _out.println(" private ClassGen _cg;"); - _out.println(); - _out.println(" public " + class_name + "Creator() {"); - _out.println(" _cg = new ClassGen(\"" - + (("".equals(package_name)) ? class_name : package_name + "." + class_name) - + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", " - + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", " - + "new String[] { " + inter + " });"); - _out.println(" _cg.setMajor(" + clazz.getMajor() +");"); - _out.println(" _cg.setMinor(" + clazz.getMinor() +");"); - _out.println(); - _out.println(" _cp = _cg.getConstantPool();"); - _out.println(" _factory = new InstructionFactory(_cg, _cp);"); - _out.println(" }"); - _out.println(); - printCreate(); - final Field[] fields = clazz.getFields(); - if (fields.length > 0) { - _out.println(" private void createFields() {"); - _out.println(" FieldGen field;"); - for (final Field field : fields) { - field.accept(this); - } - _out.println(" }"); - _out.println(); - } - final Method[] methods = clazz.getMethods(); - for (int i = 0; i < methods.length; i++) { - _out.println(" private void createMethod_" + i + "() {"); - methods[i].accept(this); - _out.println(" }"); - _out.println(); + public static void _main(final String[] argv) throws Exception { + if (argv.length != 1) { + System.out.println("Usage: BCELifier className"); + System.out.println("\tThe class must exist on the classpath"); + return; } - printMain(); - _out.println("}"); + final BCELifier bcelifier = new BCELifier(getJavaClass(argv[0]), System.out); + bcelifier.start(); } - - private void printCreate() { - _out.println(" public void create(OutputStream out) throws IOException {"); - final Field[] fields = _clazz.getFields(); - if (fields.length > 0) { - _out.println(" createFields();"); - } - final Method[] methods = _clazz.getMethods(); - for (int i = 0; i < methods.length; i++) { - _out.println(" createMethod_" + i + "();"); + static String printArgumentTypes(final Type[] argTypes) { + if (argTypes.length == 0) { + return "Type.NO_ARGS"; } - _out.println(" _cg.getJavaClass().dump(out);"); - _out.println(" }"); - _out.println(); - } - - - private void printMain() { - final String class_name = _clazz.getClassName(); - _out.println(" public static void main(String[] args) throws Exception {"); - _out.println(" " + class_name + "Creator creator = new " + class_name + "Creator();"); - _out.println(" creator.create(new FileOutputStream(\"" + class_name + ".class\"));"); - _out.println(" }"); - } - - - @Override - public void visitField( final Field field ) { - _out.println(); - _out.println(" field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", " - + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);"); - final ConstantValue cv = field.getConstantValue(); - if (cv != null) { - final String value = cv.toString(); - _out.println(" field.setInitValue(" + value + ")"); + final StringBuilder args = new StringBuilder(); + for (int i = 0; i < argTypes.length; i++) { + args.append(printType(argTypes[i])); + if (i < argTypes.length - 1) { + args.append(", "); + } } - _out.println(" _cg.addField(field.getField());"); - } - - - @Override - public void visitMethod( final Method method ) { - final MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp); - _out.println(" InstructionList il = new InstructionList();"); - _out.println(" MethodGen method = new MethodGen(" - + printFlags(method.getAccessFlags(), FLAGS.METHOD) + ", " - + printType(mg.getReturnType()) + ", " - + printArgumentTypes(mg.getArgumentTypes()) + ", " - + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) - + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);"); - _out.println(); - final BCELFactory factory = new BCELFactory(mg, _out); - factory.start(); - _out.println(" method.setMaxStack();"); - _out.println(" method.setMaxLocals();"); - _out.println(" _cg.addMethod(method.getMethod());"); - _out.println(" il.dispose();"); + return "new Type[] { " + args.toString() + " }"; } - - static String printFlags( final int flags ) { + static String printFlags(final int flags) { return printFlags(flags, FLAGS.UNKNOWN); } /** * Return a string with the flag settings + * * @param flags the flags field to interpret * @param location the item type * @return the formatted string * @since 6.0 made public */ - public static String printFlags( final int flags, final FLAGS location ) { + public static String printFlags(final int flags, final FLAGS location) { if (flags == 0) { return "0"; } final StringBuilder buf = new StringBuilder(); for (int i = 0, pow = 1; pow <= Const.MAX_ACC_FLAG_I; i++) { if ((flags & pow) != 0) { - if ((pow == Const.ACC_SYNCHRONIZED) && (location == FLAGS.CLASS)) { - buf.append(CONSTANT_PREFIX+"ACC_SUPER | "); - } else if ((pow == Const.ACC_VOLATILE) && (location == FLAGS.METHOD)) { - buf.append(CONSTANT_PREFIX+"ACC_BRIDGE | "); - } else if ((pow == Const.ACC_TRANSIENT) && (location == FLAGS.METHOD)) { - buf.append(CONSTANT_PREFIX+"ACC_VARARGS | "); + if (pow == Const.ACC_SYNCHRONIZED && location == FLAGS.CLASS) { + buf.append(CONSTANT_PREFIX).append("ACC_SUPER | "); + } else if (pow == Const.ACC_VOLATILE && location == FLAGS.METHOD) { + buf.append(CONSTANT_PREFIX).append("ACC_BRIDGE | "); + } else if (pow == Const.ACC_TRANSIENT && location == FLAGS.METHOD) { + buf.append(CONSTANT_PREFIX).append("ACC_VARARGS | "); + } else if (i < Const.ACCESS_NAMES_LENGTH) { + buf.append(CONSTANT_PREFIX).append("ACC_").append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH)).append(" | "); } else { - if (i < Const.ACCESS_NAMES_LENGTH) { - buf.append(CONSTANT_PREFIX+"ACC_") - .append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH)) - .append( " | "); - } else { - buf.append(String.format (CONSTANT_PREFIX+"ACC_BIT %x | ", pow)); - } + buf.append(String.format(CONSTANT_PREFIX + "ACC_BIT %x | ", pow)); } } pow <<= 1; @@ -241,68 +135,188 @@ return str.substring(0, str.length() - 3); } - - static String printArgumentTypes( final Type[] arg_types ) { - if (arg_types.length == 0) { - return "Type.NO_ARGS"; - } - final StringBuilder args = new StringBuilder(); - for (int i = 0; i < arg_types.length; i++) { - args.append(printType(arg_types[i])); - if (i < arg_types.length - 1) { - args.append(", "); - } - } - return "new Type[] { " + args.toString() + " }"; - } - - - static String printType( final Type type ) { - return printType(type.getSignature()); - } - - - static String printType( final String signature ) { + static String printType(final String signature) { final Type type = Type.getType(signature); final byte t = type.getType(); if (t <= Const.T_VOID) { return "Type." + Const.getTypeName(t).toUpperCase(Locale.ENGLISH); - } else if (type.toString().equals("java.lang.String")) { + } + if (type.toString().equals("java.lang.String")) { return "Type.STRING"; - } else if (type.toString().equals("java.lang.Object")) { + } + if (type.toString().equals("java.lang.Object")) { return "Type.OBJECT"; - } else if (type.toString().equals("java.lang.StringBuffer")) { + } + if (type.toString().equals("java.lang.StringBuffer")) { return "Type.STRINGBUFFER"; - } else if (type instanceof ArrayType) { + } + if (type instanceof ArrayType) { final ArrayType at = (ArrayType) type; - return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() - + ")"; - } else { - return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; + return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions() + ")"; } + return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")"; } + static String printType(final Type type) { + return printType(type.getSignature()); + } - /** Default main method + private final JavaClass clazz; + + private final PrintWriter printWriter; + + private final ConstantPoolGen constantPoolGen; + + /** + * Constructs a new instance. + * + * @param clazz Java class to "decompile". + * @param out where to print the Java program in UTF-8. */ - public static void main( final String[] argv ) throws Exception { - if (argv.length != 1) { - System.out.println("Usage: BCELifier classname"); - System.out.println("\tThe class must exist on the classpath"); - return; + public BCELifier(final JavaClass clazz, final OutputStream out) { + this.clazz = clazz; + this.printWriter = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8), false); + this.constantPoolGen = new ConstantPoolGen(this.clazz.getConstantPool()); + } + + private void printCreate() { + printWriter.println(" public void create(OutputStream out) throws IOException {"); + final Field[] fields = clazz.getFields(); + if (fields.length > 0) { + printWriter.println(" createFields();"); } - final JavaClass java_class = getJavaClass(argv[0]); - final BCELifier bcelifier = new BCELifier(java_class, System.out); - bcelifier.start(); + final Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + printWriter.println(" createMethod_" + i + "();"); + } + printWriter.println(" _cg.getJavaClass().dump(out);"); + printWriter.println(" }"); + printWriter.println(); } + private void printMain() { + final String className = clazz.getClassName(); + printWriter.println(" public static void main(String[] args) throws Exception {"); + printWriter.println(" " + className + "Creator creator = new " + className + "Creator();"); + printWriter.println(" creator.create(new FileOutputStream(\"" + className + ".class\"));"); + printWriter.println(" }"); + } - // Needs to be accessible from unit test code - static JavaClass getJavaClass(final String name) throws ClassNotFoundException, IOException { - JavaClass java_class; - if ((java_class = Repository.lookupClass(name)) == null) { - java_class = new ClassParser(name).parse(); // May throw IOException + /** + * Start Java code generation + */ + public void start() { + visitJavaClass(clazz); + printWriter.flush(); + } + + @Override + public void visitField(final Field field) { + printWriter.println(); + printWriter.println( + " field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", " + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);"); + final ConstantValue cv = field.getConstantValue(); + if (cv != null) { + printWriter.print(" field.setInitValue("); + if (field.getType() == Type.CHAR) { + printWriter.print("(char)"); + } + if (field.getType() == Type.SHORT) { + printWriter.print("(short)"); + } + if (field.getType() == Type.BYTE) { + printWriter.print("(byte)"); + } + printWriter.print(cv); + if (field.getType() == Type.LONG) { + printWriter.print("L"); + } + if (field.getType() == Type.FLOAT) { + printWriter.print("F"); + } + if (field.getType() == Type.DOUBLE) { + printWriter.print("D"); + } + printWriter.println(");"); } - return java_class; + printWriter.println(" _cg.addField(field.getField());"); + } + + @Override + public void visitJavaClass(final JavaClass clazz) { + String className = clazz.getClassName(); + final String superName = clazz.getSuperclassName(); + final String packageName = clazz.getPackageName(); + final String inter = Utility.printArray(clazz.getInterfaceNames(), false, true); + if (packageName != null && !packageName.trim().isEmpty()) { + className = className.substring(packageName.length() + 1); + printWriter.println("package " + packageName + ";"); + printWriter.println(); + } + printWriter.println("import " + BASE_PACKAGE + ".generic.*;"); + printWriter.println("import " + BASE_PACKAGE + ".classfile.*;"); + printWriter.println("import " + BASE_PACKAGE + ".*;"); + printWriter.println("import java.io.*;"); + printWriter.println(); + printWriter.println("public class " + className + "Creator {"); + printWriter.println(" private InstructionFactory _factory;"); + printWriter.println(" private ConstantPoolGen _cp;"); + printWriter.println(" private ClassGen _cg;"); + printWriter.println(); + printWriter.println(" public " + className + "Creator() {"); + printWriter.println(" _cg = new ClassGen(\"" + (packageName.isEmpty() ? className : packageName + "." + className) + "\", \"" + superName + + "\", " + "\"" + clazz.getSourceFileName() + "\", " + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", " + "new String[] { " + inter + " });"); + printWriter.println(" _cg.setMajor(" + clazz.getMajor() + ");"); + printWriter.println(" _cg.setMinor(" + clazz.getMinor() + ");"); + printWriter.println(); + printWriter.println(" _cp = _cg.getConstantPool();"); + printWriter.println(" _factory = new InstructionFactory(_cg, _cp);"); + printWriter.println(" }"); + printWriter.println(); + printCreate(); + final Field[] fields = clazz.getFields(); + if (fields.length > 0) { + printWriter.println(" private void createFields() {"); + printWriter.println(" FieldGen field;"); + for (final Field field : fields) { + field.accept(this); + } + printWriter.println(" }"); + printWriter.println(); + } + final Method[] methods = clazz.getMethods(); + for (int i = 0; i < methods.length; i++) { + printWriter.println(" private void createMethod_" + i + "() {"); + methods[i].accept(this); + printWriter.println(" }"); + printWriter.println(); + } + printMain(); + printWriter.println("}"); + } + + @Override + public void visitMethod(final Method method) { + final MethodGen mg = new MethodGen(method, clazz.getClassName(), constantPoolGen); + printWriter.println(" InstructionList il = new InstructionList();"); + printWriter.println(" MethodGen method = new MethodGen(" + printFlags(method.getAccessFlags(), FLAGS.METHOD) + ", " + printType(mg.getReturnType()) + + ", " + printArgumentTypes(mg.getArgumentTypes()) + ", " + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) + " }, \"" + + method.getName() + "\", \"" + clazz.getClassName() + "\", il, _cp);"); + final ExceptionTable exceptionTable = method.getExceptionTable(); + if (exceptionTable != null) { + final String[] exceptionNames = exceptionTable.getExceptionNames(); + for (final String exceptionName : exceptionNames) { + printWriter.print(" method.addException(\""); + printWriter.print(exceptionName); + printWriter.println("\");"); + } + } + printWriter.println(); + final BCELFactory factory = new BCELFactory(mg, printWriter); + factory.start(); + printWriter.println(" method.setMaxStack();"); + printWriter.println(" method.setMaxLocals();"); + printWriter.println(" _cg.addMethod(method.getMethod());"); + printWriter.println(" il.dispose();"); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ByteSequence.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,31 +25,11 @@ import java.io.DataInputStream; /** - * Utility class that implements a sequence of bytes which can be read - * via the `readByte()' method. This is used to implement a wrapper for the - * Java byte code stream to gain some more readability. - * + * Utility class that implements a sequence of bytes which can be read via the 'readByte()' method. This is used to + * implement a wrapper for the Java byte code stream to gain some more readability. */ public final class ByteSequence extends DataInputStream { - private final ByteArrayStream byteStream; - - - public ByteSequence(final byte[] bytes) { - super(new ByteArrayStream(bytes)); - byteStream = (ByteArrayStream) in; - } - - - public int getIndex() { - return byteStream.getPosition(); - } - - - void unreadByte() { - byteStream.unreadByte(); - } - private static final class ByteArrayStream extends ByteArrayInputStream { ByteArrayStream(final byte[] bytes) { @@ -67,4 +47,19 @@ } } } + + private final ByteArrayStream byteStream; + + public ByteSequence(final byte[] bytes) { + super(new ByteArrayStream(bytes)); + byteStream = (ByteArrayStream) in; + } + + public int getIndex() { + return byteStream.getPosition(); + } + + void unreadByte() { + byteStream.unreadByte(); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Class2HTML.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,9 +20,12 @@ package com.sun.org.apache.bcel.internal.util; import java.io.File; -import java.io.FileOutputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.Set; @@ -37,89 +40,49 @@ /** * Read class file(s) and convert them into HTML files. * - * Given a JavaClass object "class" that is in package "package" five files - * will be created in the specified directory. + * Given a JavaClass object "class" that is in package "package" five files will be created in the specified directory. * *

      - *
    1. "package"."class".html as the main file which defines the frames for - * the following subfiles. - *
    2. "package"."class"_attributes.html contains all (known) attributes found in the file - *
    3. "package"."class"_cp.html contains the constant pool - *
    4. "package"."class"_code.html contains the byte code - *
    5. "package"."class"_methods.html contains references to all methods and fields of the class + *
    6. "package"."class".html as the main file which defines the frames for the following subfiles. + *
    7. "package"."class"_attributes.html contains all (known) attributes found in the file + *
    8. "package"."class"_cp.html contains the constant pool + *
    9. "package"."class"_code.html contains the byte code + *
    10. "package"."class"_methods.html contains references to all methods and fields of the class *
    * - * All subfiles reference each other appropriately, e.g. clicking on a - * method in the Method's frame will jump to the appropriate method in - * the Code frame. + * All subfiles reference each other appropriately, e.g. clicking on a method in the Method's frame will jump to the + * appropriate method in the Code frame. * - * @LastModified: Jan 2020 + * @LastModified: Feb 2023 */ public class Class2HTML { - private final JavaClass java_class; // current class object - private final String dir; - private static String class_package; // name of package, unclean to make it static, but ... - private static String class_name; // name of current class, dito - private static ConstantPool constant_pool; - private static final Set basic_types = new HashSet<>(); - + private static String classPackage; // name of package, unclean to make it static, but ... + private static String className; // name of current class, dito + private static ConstantPool constantPool; + private static final Set basicTypes = new HashSet<>(); static { - basic_types.add("int"); - basic_types.add("short"); - basic_types.add("boolean"); - basic_types.add("void"); - basic_types.add("char"); - basic_types.add("byte"); - basic_types.add("long"); - basic_types.add("double"); - basic_types.add("float"); + basicTypes.add("int"); + basicTypes.add("short"); + basicTypes.add("boolean"); + basicTypes.add("void"); + basicTypes.add("char"); + basicTypes.add("byte"); + basicTypes.add("long"); + basicTypes.add("double"); + basicTypes.add("float"); } - /** - * Write contents of the given JavaClass into HTML files. - * - * @param java_class The class to write - * @param dir The directory to put the files in - */ - public Class2HTML(final JavaClass java_class, final String dir) throws IOException { - final Method[] methods = java_class.getMethods(); - this.java_class = java_class; - this.dir = dir; - class_name = java_class.getClassName(); // Remember full name - constant_pool = java_class.getConstantPool(); - // Get package name by tacking off everything after the last `.' - final int index = class_name.lastIndexOf('.'); - if (index > -1) { - class_package = class_name.substring(0, index); - } else { - class_package = ""; // default package - } - final ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods, - constant_pool); - /* Attributes can't be written in one step, so we just open a file - * which will be written consequently. - */ - final AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, - constant_html); - new MethodHTML(dir, class_name, methods, java_class.getFields(), - constant_html, attribute_html); - // Write main file (with frames, yuk) - writeMainHTML(attribute_html); - new CodeHTML(dir, class_name, methods, constant_pool, constant_html); - attribute_html.close(); - } - - - public static void main( final String[] argv ) throws IOException { - final String[] file_name = new String[argv.length]; + public static void _main(final String[] argv) throws IOException { + final String[] fileName = new String[argv.length]; int files = 0; ClassParser parser = null; - JavaClass java_class = null; - String zip_file = null; + JavaClass javaClass = null; + String zipFile = null; final char sep = File.separatorChar; String dir = "." + sep; // Where to store HTML files - /* Parse command line arguments. + /* + * Parse command line arguments. */ for (int i = 0; i < argv.length; i++) { if (argv[i].charAt(0) == '-') { // command line switch @@ -131,108 +94,138 @@ final File store = new File(dir); if (!store.isDirectory()) { final boolean created = store.mkdirs(); // Create target directory if necessary - if (!created) { - if (!store.isDirectory()) { - System.out.println("Tried to create the directory " + dir + " but failed"); - } + if (!created && !store.isDirectory()) { + System.out.println("Tried to create the directory " + dir + " but failed"); } } } else if (argv[i].equals("-zip")) { - zip_file = argv[++i]; + zipFile = argv[++i]; } else { System.out.println("Unknown option " + argv[i]); } } else { - file_name[files++] = argv[i]; + fileName[files++] = argv[i]; } } if (files == 0) { System.err.println("Class2HTML: No input files specified."); } else { // Loop through files ... for (int i = 0; i < files; i++) { - System.out.print("Processing " + file_name[i] + "..."); - if (zip_file == null) { - parser = new ClassParser(file_name[i]); // Create parser object from file + System.out.print("Processing " + fileName[i] + "..."); + if (zipFile == null) { + parser = new ClassParser(fileName[i]); // Create parser object from file } else { - parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file + parser = new ClassParser(zipFile, fileName[i]); // Create parser object from zip file } - java_class = parser.parse(); - new Class2HTML(java_class, dir); + javaClass = parser.parse(); + new Class2HTML(javaClass, dir); System.out.println("Done."); } } } /** - * Utility method that converts a class reference in the constant pool, - * i.e., an index to a string. + * Utility method that converts a class reference in the constant pool, i.e., an index to a string. */ static String referenceClass(final int index) { - String str = constant_pool.getConstantString(index, Const.CONSTANT_Class); + String str = constantPool.getConstantString(index, Const.CONSTANT_Class); str = Utility.compactClassName(str); - str = Utility.compactClassName(str, class_package + ".", true); - return "" + str - + ""; + str = Utility.compactClassName(str, classPackage + ".", true); + return "" + str + ""; } - - static String referenceType( final String type ) { - String short_type = Utility.compactClassName(type); - short_type = Utility.compactClassName(short_type, class_package + ".", true); + static String referenceType(final String type) { + String shortType = Utility.compactClassName(type); + shortType = Utility.compactClassName(shortType, classPackage + ".", true); final int index = type.indexOf('['); // Type is an array? - String base_type = type; + String baseType = type; if (index > -1) { - base_type = type.substring(0, index); // Tack of the `[' + baseType = type.substring(0, index); // Tack of the '[' } // test for basic type - if (basic_types.contains(base_type)) { + if (basicTypes.contains(baseType)) { return "" + type + ""; } - return "" + short_type + ""; + return "" + shortType + ""; } - - static String toHTML( final String str ) { + static String toHTML(final String str) { final StringBuilder buf = new StringBuilder(); for (int i = 0; i < str.length(); i++) { char ch; switch (ch = str.charAt(i)) { - case '<': - buf.append("<"); - break; - case '>': - buf.append(">"); - break; - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - default: - buf.append(ch); + case '<': + buf.append("<"); + break; + case '>': + buf.append(">"); + break; + case '\n': + buf.append("\\n"); + break; + case '\r': + buf.append("\\r"); + break; + default: + buf.append(ch); } } return buf.toString(); } + private final JavaClass javaClass; // current class object + + private final String dir; + + /** + * Write contents of the given JavaClass into HTML files. + * + * @param javaClass The class to write + * @param dir The directory to put the files in + * @throws IOException Thrown when an I/O exception of some sort has occurred. + */ + public Class2HTML(final JavaClass javaClass, final String dir) throws IOException { + this(javaClass, dir, StandardCharsets.UTF_8); + } + + private Class2HTML(final JavaClass javaClass, final String dir, final Charset charset) throws IOException { + final Method[] methods = javaClass.getMethods(); + this.javaClass = javaClass; + this.dir = dir; + className = javaClass.getClassName(); // Remember full name + constantPool = javaClass.getConstantPool(); + // Get package name by tacking off everything after the last '.' + final int index = className.lastIndexOf('.'); + if (index > -1) { + classPackage = className.substring(0, index); + } else { + classPackage = ""; // default package + } + final ConstantHTML constantHtml = new ConstantHTML(dir, className, classPackage, methods, constantPool, charset); + /* + * Attributes can't be written in one step, so we just open a file which will be written consequently. + */ + try (AttributeHTML attributeHtml = new AttributeHTML(dir, className, constantPool, constantHtml, charset)) { + new MethodHTML(dir, className, methods, javaClass.getFields(), constantHtml, attributeHtml, charset); + // Write main file (with frames, yuk) + writeMainHTML(attributeHtml, charset); + new CodeHTML(dir, className, methods, constantPool, constantHtml, charset); + } + } - private void writeMainHTML( final AttributeHTML attribute_html ) throws IOException { - try (PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html"))) { - file.println("\n" + "Documentation for " + class_name + "" + "\n" - + "\n" + "\n" - + "\n" + "\n" + "\n" - + "\n" + "\n" - + "\n" + ""); + private void writeMainHTML(final AttributeHTML attributeHtml, final Charset charset) throws FileNotFoundException, UnsupportedEncodingException { + try (PrintWriter file = new PrintWriter(dir + className + ".html", charset.name())) { + file.println("\n" + "Documentation for " + className + "" + "\n" + "\n" + + "\n" + "\n" + "\n" + "\n" + + "\n" + "\n" + "\n" + ""); } - final Attribute[] attributes = java_class.getAttributes(); + final Attribute[] attributes = javaClass.getAttributes(); for (int i = 0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], "class" + i); + attributeHtml.writeAttribute(attributes[i], "class" + i); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassQueue.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,30 +24,28 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Utility class implementing a (typesafe) queue of JavaClass - * objects. - * + * Utility class implementing a (typesafe) queue of JavaClass objects. * @LastModified: Jan 2020 */ public class ClassQueue { - private final LinkedList vec = new LinkedList<>(); - - - public void enqueue( final JavaClass clazz ) { - vec.addLast(clazz); - } - + /** + * @deprecated (since 6.0) will be made private; do not access + */ + @Deprecated + protected LinkedList vec = new LinkedList<>(); // TODO not used externally public JavaClass dequeue() { return vec.removeFirst(); } - public boolean empty() { return vec.isEmpty(); } + public void enqueue(final JavaClass clazz) { + vec.addLast(clazz); + } @Override public String toString() { diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassSet.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -21,53 +20,39 @@ package com.sun.org.apache.bcel.internal.util; -import java.util.Collection; +import com.sun.org.apache.bcel.internal.Const; import java.util.HashMap; import java.util.Map; import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Utility class implementing a (typesafe) set of JavaClass objects. - * Since JavaClass has no equals() method, the name of the class is - * used for comparison. + * Utility class implementing a (type-safe) set of JavaClass objects. Since JavaClass has no equals() method, the name of the class is used for comparison. * * @see ClassStack + * @LastModified: Feb 2023 */ public class ClassSet { private final Map map = new HashMap<>(); - - public boolean add( final JavaClass clazz ) { - boolean result = false; - if (!map.containsKey(clazz.getClassName())) { - result = true; - map.put(clazz.getClassName(), clazz); - } - return result; + public boolean add(final JavaClass clazz) { + return map.putIfAbsent(clazz.getClassName(), clazz) != null; } - - public void remove( final JavaClass clazz ) { - map.remove(clazz.getClassName()); - } - - public boolean empty() { return map.isEmpty(); } - - public JavaClass[] toArray() { - final Collection values = map.values(); - final JavaClass[] classes = new JavaClass[values.size()]; - values.toArray(classes); - return classes; + public String[] getClassNames() { + return map.keySet().toArray(Const.EMPTY_STRING_ARRAY); } + public void remove(final JavaClass clazz) { + map.remove(clazz.getClassName()); + } - public String[] getClassNames() { - return map.keySet().toArray(new String[map.size()]); + public JavaClass[] toArray() { + return map.values().toArray(JavaClass.EMPTY_ARRAY); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ClassStack.java 2023-10-06 05:33:33.000000000 +0000 @@ -34,23 +34,19 @@ private final Stack stack = new Stack<>(); - - public void push( final JavaClass clazz ) { - stack.push(clazz); + public boolean empty() { + return stack.empty(); } - public JavaClass pop() { return stack.pop(); } + public void push(final JavaClass clazz) { + stack.push(clazz); + } public JavaClass top() { return stack.peek(); } - - - public boolean empty() { - return stack.empty(); - } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/CodeHTML.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,9 +21,9 @@ package com.sun.org.apache.bcel.internal.util; -import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import java.nio.charset.Charset; import java.util.BitSet; import com.sun.org.apache.bcel.internal.Const; @@ -36,363 +36,349 @@ import com.sun.org.apache.bcel.internal.classfile.ConstantMethodref; import com.sun.org.apache.bcel.internal.classfile.ConstantNameAndType; import com.sun.org.apache.bcel.internal.classfile.ConstantPool; -import com.sun.org.apache.bcel.internal.classfile.LocalVariable; import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable; import com.sun.org.apache.bcel.internal.classfile.Method; import com.sun.org.apache.bcel.internal.classfile.Utility; /** * Convert code into HTML file. - * - * */ final class CodeHTML { + private static boolean wide; private final String className; // name of current class -// private Method[] methods; // Methods to print - private final PrintWriter file; // file to write to + // private Method[] methods; // Methods to print + private final PrintWriter printWriter; // file to write to private BitSet gotoSet; private final ConstantPool constantPool; private final ConstantHTML constantHtml; - private static boolean wide = false; - - CodeHTML(final String dir, final String class_name, final Method[] methods, final ConstantPool constant_pool, - final ConstantHTML constant_html) throws IOException { - this.className = class_name; + CodeHTML(final String dir, final String className, final Method[] methods, final ConstantPool constantPool, final ConstantHTML constantHtml, + final Charset charset) throws IOException { + this.className = className; // this.methods = methods; - this.constantPool = constant_pool; - this.constantHtml = constant_html; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html")); - file.println(""); - for (int i = 0; i < methods.length; i++) { - writeMethod(methods[i], i); + this.constantPool = constantPool; + this.constantHtml = constantHtml; + try (PrintWriter newPrintWriter = new PrintWriter(dir + className + "_code.html", charset.name())) { + printWriter = newPrintWriter; + printWriter.print(""); + printWriter.println(""); + for (int i = 0; i < methods.length; i++) { + writeMethod(methods[i], i); + } + printWriter.println(""); } - file.println(""); - file.close(); } - /** - * Disassemble a stream of byte codes and return the - * string representation. + * Disassemble a stream of byte codes and return the string representation. * - * @param stream data input stream + * @param stream data input stream * @return String representation of byte code */ - private String codeToHTML( final ByteSequence bytes, final int method_number ) throws IOException { + private String codeToHTML(final ByteSequence bytes, final int methodNumber) throws IOException { final short opcode = (short) bytes.readUnsignedByte(); String name; String signature; - int default_offset = 0; + int defaultOffset = 0; int low; int high; int index; - int class_index; + int classIndex; int vindex; int constant; - int[] jump_table; - int no_pad_bytes = 0; + int[] jumpTable; + int noPadBytes = 0; int offset; final StringBuilder buf = new StringBuilder(256); // CHECKSTYLE IGNORE MagicNumber buf.append("").append(Const.getOpcodeName(opcode)).append(""); - /* Special case: Skip (0-3) padding bytes, i.e., the - * following bytes are 4-byte-aligned + /* + * Special case: Skip (0-3) padding bytes, i.e., the following bytes are 4-byte-aligned */ - if ((opcode == Const.TABLESWITCH) || (opcode == Const.LOOKUPSWITCH)) { + if (opcode == Const.TABLESWITCH || opcode == Const.LOOKUPSWITCH) { final int remainder = bytes.getIndex() % 4; - no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; - for (int i = 0; i < no_pad_bytes; i++) { + noPadBytes = remainder == 0 ? 0 : 4 - remainder; + for (int i = 0; i < noPadBytes; i++) { bytes.readByte(); } // Both cases have a field default_offset in common - default_offset = bytes.readInt(); + defaultOffset = bytes.readInt(); } switch (opcode) { - case Const.TABLESWITCH: - low = bytes.readInt(); - high = bytes.readInt(); - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - buf.append(""); - // Print switch indices in first row (and default) - jump_table = new int[high - low + 1]; - for (int i = 0; i < jump_table.length; i++) { - jump_table[i] = offset + bytes.readInt(); - buf.append(""); - } - buf.append("\n"); - // Print target and default indices in second row - for (final int element : jump_table) { - buf.append(""); - } - buf.append("\n
    ").append(low + i).append("default
    ").append(element).append("").append(default_offset).append( - "
    \n"); - break; - /* Lookup switch has variable length arguments. - */ - case Const.LOOKUPSWITCH: - final int npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - jump_table = new int[npairs]; - default_offset += offset; - buf.append(""); - // Print switch indices in first row (and default) - for (int i = 0; i < npairs; i++) { - final int match = bytes.readInt(); - jump_table[i] = offset + bytes.readInt(); - buf.append(""); - } - buf.append("\n"); - // Print target and default indices in second row - for (int i = 0; i < npairs; i++) { - buf.append(""); - } - buf.append("\n
    ").append(match).append("default
    ").append(jump_table[i]).append("").append(default_offset).append( - "
    \n"); - break; - /* Two address bytes + offset from start of byte stream form the - * jump target. - */ - case Const.GOTO: - case Const.IFEQ: - case Const.IFGE: - case Const.IFGT: - case Const.IFLE: - case Const.IFLT: - case Const.IFNE: - case Const.IFNONNULL: - case Const.IFNULL: - case Const.IF_ACMPEQ: - case Const.IF_ACMPNE: - case Const.IF_ICMPEQ: - case Const.IF_ICMPGE: - case Const.IF_ICMPGT: - case Const.IF_ICMPLE: - case Const.IF_ICMPLT: - case Const.IF_ICMPNE: - case Const.JSR: - index = bytes.getIndex() + bytes.readShort() - 1; - buf.append("").append(index).append(""); - break; - /* Same for 32-bit wide jumps - */ - case Const.GOTO_W: - case Const.JSR_W: - final int windex = bytes.getIndex() + bytes.readInt() - 1; - buf.append("").append(windex).append(""); - break; - /* Index byte references local variable (register) - */ - case Const.ALOAD: - case Const.ASTORE: - case Const.DLOAD: - case Const.DSTORE: - case Const.FLOAD: - case Const.FSTORE: - case Const.ILOAD: - case Const.ISTORE: - case Const.LLOAD: - case Const.LSTORE: - case Const.RET: - if (wide) { - vindex = bytes.readShort(); - wide = false; // Clear flag - } else { - vindex = bytes.readUnsignedByte(); - } - buf.append("%").append(vindex); - break; - /* - * Remember wide byte which is used to form a 16-bit address in the - * following instruction. Relies on that the method is called again with - * the following opcode. - */ - case Const.WIDE: - wide = true; - buf.append("(wide)"); - break; - /* Array of basic type. - */ - case Const.NEWARRAY: - buf.append("").append(Const.getTypeName(bytes.readByte())).append( - ""); - break; - /* Access object/class fields. - */ - case Const.GETFIELD: - case Const.GETSTATIC: - case Const.PUTFIELD: - case Const.PUTSTATIC: - index = bytes.readShort(); - final ConstantFieldref c1 = (ConstantFieldref) constantPool.getConstant(index, - Const.CONSTANT_Fieldref); - class_index = c1.getClassIndex(); - name = constantPool.getConstantString(class_index, Const.CONSTANT_Class); - name = Utility.compactClassName(name, false); - index = c1.getNameAndTypeIndex(); - final String field_name = constantPool.constantToString(index, Const.CONSTANT_NameAndType); - if (name.equals(className)) { // Local field - buf.append("").append(field_name) - .append("\n"); - } else { - buf.append(constantHtml.referenceConstant(class_index)).append(".").append( - field_name); - } - break; - /* Operands are references to classes in constant pool - */ - case Const.CHECKCAST: - case Const.INSTANCEOF: - case Const.NEW: - index = bytes.readShort(); - buf.append(constantHtml.referenceConstant(index)); - break; - /* Operands are references to methods in constant pool - */ - case Const.INVOKESPECIAL: - case Const.INVOKESTATIC: - case Const.INVOKEVIRTUAL: - case Const.INVOKEINTERFACE: - case Const.INVOKEDYNAMIC: - final int m_index = bytes.readShort(); - String str; - if (opcode == Const.INVOKEINTERFACE) { // Special treatment needed - bytes.readUnsignedByte(); // Redundant - bytes.readUnsignedByte(); // Reserved + case Const.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + offset = bytes.getIndex() - 12 - noPadBytes - 1; + defaultOffset += offset; + buf.append(""); + // Print switch indices in first row (and default) + jumpTable = new int[high - low + 1]; + for (int i = 0; i < jumpTable.length; i++) { + jumpTable[i] = offset + bytes.readInt(); + buf.append(""); + } + buf.append("\n"); + // Print target and default indices in second row + for (final int element : jumpTable) { + buf.append(""); + } + buf.append("\n
    ").append(low + i).append("default
    ").append(element).append("").append(defaultOffset) + .append("
    \n"); + break; + /* + * Lookup switch has variable length arguments. + */ + case Const.LOOKUPSWITCH: + final int npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - noPadBytes - 1; + jumpTable = new int[npairs]; + defaultOffset += offset; + buf.append(""); + // Print switch indices in first row (and default) + for (int i = 0; i < npairs; i++) { + final int match = bytes.readInt(); + jumpTable[i] = offset + bytes.readInt(); + buf.append(""); + } + buf.append("\n"); + // Print target and default indices in second row + for (int i = 0; i < npairs; i++) { + buf.append(""); + } + buf.append("\n
    ").append(match).append("default
    ").append(jumpTable[i]) + .append("").append(defaultOffset) + .append("
    \n"); + break; + /* + * Two address bytes + offset from start of byte stream form the jump target. + */ + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.JSR: + index = bytes.getIndex() + bytes.readShort() - 1; + buf.append("").append(index).append(""); + break; + /* + * Same for 32-bit wide jumps + */ + case Const.GOTO_W: + case Const.JSR_W: + final int windex = bytes.getIndex() + bytes.readInt() - 1; + buf.append("").append(windex).append(""); + break; + /* + * Index byte references local variable (register) + */ + case Const.ALOAD: + case Const.ASTORE: + case Const.DLOAD: + case Const.DSTORE: + case Const.FLOAD: + case Const.FSTORE: + case Const.ILOAD: + case Const.ISTORE: + case Const.LLOAD: + case Const.LSTORE: + case Const.RET: + if (wide) { + vindex = bytes.readShort(); + wide = false; // Clear flag + } else { + vindex = bytes.readUnsignedByte(); + } + buf.append("%").append(vindex); + break; + /* + * Remember wide byte which is used to form a 16-bit address in the following instruction. Relies on that the method is + * called again with the following opcode. + */ + case Const.WIDE: + wide = true; + buf.append("(wide)"); + break; + /* + * Array of basic type. + */ + case Const.NEWARRAY: + buf.append("").append(Const.getTypeName(bytes.readByte())).append(""); + break; + /* + * Access object/class fields. + */ + case Const.GETFIELD: + case Const.GETSTATIC: + case Const.PUTFIELD: + case Const.PUTSTATIC: + index = bytes.readShort(); + final ConstantFieldref c1 = constantPool.getConstant(index, Const.CONSTANT_Fieldref, ConstantFieldref.class); + classIndex = c1.getClassIndex(); + name = constantPool.getConstantString(classIndex, Const.CONSTANT_Class); + name = Utility.compactClassName(name, false); + index = c1.getNameAndTypeIndex(); + final String fieldName = constantPool.constantToString(index, Const.CONSTANT_NameAndType); + if (name.equals(className)) { // Local field + buf.append("").append(fieldName) + .append("\n"); + } else { + buf.append(constantHtml.referenceConstant(classIndex)).append(".").append(fieldName); + } + break; + /* + * Operands are references to classes in constant pool + */ + case Const.CHECKCAST: + case Const.INSTANCEOF: + case Const.NEW: + index = bytes.readShort(); + buf.append(constantHtml.referenceConstant(index)); + break; + /* + * Operands are references to methods in constant pool + */ + case Const.INVOKESPECIAL: + case Const.INVOKESTATIC: + case Const.INVOKEVIRTUAL: + case Const.INVOKEINTERFACE: + case Const.INVOKEDYNAMIC: + final int mIndex = bytes.readShort(); + String str; + if (opcode == Const.INVOKEINTERFACE) { // Special treatment needed + bytes.readUnsignedByte(); // Redundant + bytes.readUnsignedByte(); // Reserved // int nargs = bytes.readUnsignedByte(); // Redundant // int reserved = bytes.readUnsignedByte(); // Reserved - final ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constantPool - .getConstant(m_index, Const.CONSTANT_InterfaceMethodref); - class_index = c.getClassIndex(); - index = c.getNameAndTypeIndex(); - name = Class2HTML.referenceClass(class_index); - } else if (opcode == Const.INVOKEDYNAMIC) { // Special treatment needed - bytes.readUnsignedByte(); // Reserved - bytes.readUnsignedByte(); // Reserved - final ConstantInvokeDynamic c = (ConstantInvokeDynamic) constantPool - .getConstant(m_index, Const.CONSTANT_InvokeDynamic); - index = c.getNameAndTypeIndex(); - name = "#" + c.getBootstrapMethodAttrIndex(); - } else { - // UNDONE: Java8 now allows INVOKESPECIAL and INVOKESTATIC to - // reference EITHER a Methodref OR an InterfaceMethodref. - // Not sure if that affects this code or not. (markro) - final ConstantMethodref c = (ConstantMethodref) constantPool.getConstant(m_index, - Const.CONSTANT_Methodref); - class_index = c.getClassIndex(); - index = c.getNameAndTypeIndex(); - name = Class2HTML.referenceClass(class_index); - } - str = Class2HTML.toHTML(constantPool.constantToString(constantPool.getConstant( - index, Const.CONSTANT_NameAndType))); - // Get signature, i.e., types - final ConstantNameAndType c2 = (ConstantNameAndType) constantPool.getConstant(index, - Const.CONSTANT_NameAndType); - signature = constantPool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); - final String[] args = Utility.methodSignatureArgumentTypes(signature, false); - final String type = Utility.methodSignatureReturnType(signature, false); - buf.append(name).append(".").append(str).append( - "").append("("); - // List arguments - for (int i = 0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - if (i < args.length - 1) { - buf.append(", "); - } - } - // Attach return type - buf.append("):").append(Class2HTML.referenceType(type)); - break; - /* Operands are references to items in constant pool - */ - case Const.LDC_W: - case Const.LDC2_W: - index = bytes.readShort(); - buf.append("").append( - Class2HTML.toHTML(constantPool.constantToString(index, - constantPool.getConstant(index).getTag()))).append(""); - break; - case Const.LDC: - index = bytes.readUnsignedByte(); - buf.append("").append( - Class2HTML.toHTML(constantPool.constantToString(index, - constantPool.getConstant(index).getTag()))).append(""); - break; - /* Array of references. - */ - case Const.ANEWARRAY: - index = bytes.readShort(); - buf.append(constantHtml.referenceConstant(index)); - break; - /* Multidimensional array of references. - */ - case Const.MULTIANEWARRAY: - index = bytes.readShort(); - final int dimensions = bytes.readByte(); - buf.append(constantHtml.referenceConstant(index)).append(":").append(dimensions) - .append("-dimensional"); - break; - /* Increment local variable. - */ - case Const.IINC: - if (wide) { - vindex = bytes.readShort(); - constant = bytes.readShort(); - wide = false; - } else { - vindex = bytes.readUnsignedByte(); - constant = bytes.readByte(); + final ConstantInterfaceMethodref c = constantPool.getConstant(mIndex, Const.CONSTANT_InterfaceMethodref, ConstantInterfaceMethodref.class); + classIndex = c.getClassIndex(); + index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(classIndex); + } else if (opcode == Const.INVOKEDYNAMIC) { // Special treatment needed + bytes.readUnsignedByte(); // Reserved + bytes.readUnsignedByte(); // Reserved + final ConstantInvokeDynamic c = constantPool.getConstant(mIndex, Const.CONSTANT_InvokeDynamic, ConstantInvokeDynamic.class); + index = c.getNameAndTypeIndex(); + name = "#" + c.getBootstrapMethodAttrIndex(); + } else { + // UNDONE: Java8 now allows INVOKESPECIAL and INVOKESTATIC to + // reference EITHER a Methodref OR an InterfaceMethodref. + // Not sure if that affects this code or not. (markro) + final ConstantMethodref c = constantPool.getConstant(mIndex, Const.CONSTANT_Methodref, ConstantMethodref.class); + classIndex = c.getClassIndex(); + index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(classIndex); + } + str = Class2HTML.toHTML(constantPool.constantToString(constantPool.getConstant(index, Const.CONSTANT_NameAndType))); + // Get signature, i.e., types + final ConstantNameAndType c2 = constantPool.getConstant(index, Const.CONSTANT_NameAndType, ConstantNameAndType.class); + signature = constantPool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + final String type = Utility.methodSignatureReturnType(signature, false); + buf.append(name).append(".").append(str) + .append("").append("("); + // List arguments + for (int i = 0; i < args.length; i++) { + buf.append(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + buf.append(", "); } - buf.append("%").append(vindex).append(" ").append(constant); - break; - default: - if (Const.getNoOfOperands(opcode) > 0) { - for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { - switch (Const.getOperandType(opcode, i)) { - case Const.T_BYTE: - buf.append(bytes.readUnsignedByte()); - break; - case Const.T_SHORT: // Either branch or index - buf.append(bytes.readShort()); - break; - case Const.T_INT: - buf.append(bytes.readInt()); - break; - default: // Never reached - throw new IllegalStateException( - "Unreachable default case reached! " + - Const.getOperandType(opcode, i)); - } - buf.append(" "); + } + // Attach return type + buf.append("):").append(Class2HTML.referenceType(type)); + break; + /* + * Operands are references to items in constant pool + */ + case Const.LDC_W: + case Const.LDC2_W: + index = bytes.readShort(); + buf.append("") + .append(Class2HTML.toHTML(constantPool.constantToString(index, constantPool.getConstant(index).getTag()))).append(""); + break; + case Const.LDC: + index = bytes.readUnsignedByte(); + buf.append("") + .append(Class2HTML.toHTML(constantPool.constantToString(index, constantPool.getConstant(index).getTag()))).append(""); + break; + /* + * Array of references. + */ + case Const.ANEWARRAY: + index = bytes.readShort(); + buf.append(constantHtml.referenceConstant(index)); + break; + /* + * Multidimensional array of references. + */ + case Const.MULTIANEWARRAY: + index = bytes.readShort(); + final int dimensions = bytes.readByte(); + buf.append(constantHtml.referenceConstant(index)).append(":").append(dimensions).append("-dimensional"); + break; + /* + * Increment local variable. + */ + case Const.IINC: + if (wide) { + vindex = bytes.readShort(); + constant = bytes.readShort(); + wide = false; + } else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("%").append(vindex).append(" ").append(constant); + break; + default: + if (Const.getNoOfOperands(opcode) > 0) { + for (int i = 0; i < Const.getOperandTypeCount(opcode); i++) { + switch (Const.getOperandType(opcode, i)) { + case Const.T_BYTE: + buf.append(bytes.readUnsignedByte()); + break; + case Const.T_SHORT: // Either branch or index + buf.append(bytes.readShort()); + break; + case Const.T_INT: + buf.append(bytes.readInt()); + break; + default: // Never reached + throw new IllegalStateException("Unreachable default case reached! " + Const.getOperandType(opcode, i)); } + buf.append(" "); } + } } buf.append(""); return buf.toString(); } - /** - * Find all target addresses in code, so that they can be marked - * with <A NAME = ...>. Target addresses are kept in an BitSet object. + * Find all target addresses in code, so that they can be marked with <A NAME = ...>. Target addresses are kept in + * an BitSet object. */ - private void findGotos( final ByteSequence bytes, final Code code ) throws IOException { + private void findGotos(final ByteSequence bytes, final Code code) throws IOException { int index; gotoSet = new BitSet(bytes.available()); int opcode; - /* First get Code attribute from method and the exceptions handled - * (try .. catch) in this method. We only need the line number here. + /* + * First get Code attribute from method and the exceptions handled (try .. catch) in this method. We only need the line + * number here. */ if (code != null) { final CodeException[] ce = code.getExceptionTable(); @@ -405,98 +391,94 @@ final Attribute[] attributes = code.getAttributes(); for (final Attribute attribute : attributes) { if (attribute.getTag() == Const.ATTR_LOCAL_VARIABLE_TABLE) { - final LocalVariable[] vars = ((LocalVariableTable) attribute) - .getLocalVariableTable(); - for (final LocalVariable var : vars) { + ((LocalVariableTable) attribute).forEach(var -> { final int start = var.getStartPC(); - final int end = start + var.getLength(); gotoSet.set(start); - gotoSet.set(end); - } + gotoSet.set(start + var.getLength()); + }); break; } } } // Get target addresses from GOTO, JSR, TABLESWITCH, etc. - for (; bytes.available() > 0;) { + while (bytes.available() > 0) { opcode = bytes.readUnsignedByte(); - //System.out.println(getOpcodeName(opcode)); + // System.out.println(getOpcodeName(opcode)); switch (opcode) { - case Const.TABLESWITCH: - case Const.LOOKUPSWITCH: - //bytes.readByte(); // Skip already read byte - final int remainder = bytes.getIndex() % 4; - final int no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder; - int default_offset; - int offset; - for (int j = 0; j < no_pad_bytes; j++) { - bytes.readByte(); + case Const.TABLESWITCH: + case Const.LOOKUPSWITCH: + // bytes.readByte(); // Skip already read byte + final int remainder = bytes.getIndex() % 4; + final int noPadBytes = remainder == 0 ? 0 : 4 - remainder; + int defaultOffset; + int offset; + for (int j = 0; j < noPadBytes; j++) { + bytes.readByte(); + } + // Both cases have a field default_offset in common + defaultOffset = bytes.readInt(); + if (opcode == Const.TABLESWITCH) { + final int low = bytes.readInt(); + final int high = bytes.readInt(); + offset = bytes.getIndex() - 12 - noPadBytes - 1; + defaultOffset += offset; + gotoSet.set(defaultOffset); + for (int j = 0; j < high - low + 1; j++) { + index = offset + bytes.readInt(); + gotoSet.set(index); } - // Both cases have a field default_offset in common - default_offset = bytes.readInt(); - if (opcode == Const.TABLESWITCH) { - final int low = bytes.readInt(); - final int high = bytes.readInt(); - offset = bytes.getIndex() - 12 - no_pad_bytes - 1; - default_offset += offset; - gotoSet.set(default_offset); - for (int j = 0; j < (high - low + 1); j++) { - index = offset + bytes.readInt(); - gotoSet.set(index); - } - } else { // LOOKUPSWITCH - final int npairs = bytes.readInt(); - offset = bytes.getIndex() - 8 - no_pad_bytes - 1; - default_offset += offset; - gotoSet.set(default_offset); - for (int j = 0; j < npairs; j++) { + } else { // LOOKUPSWITCH + final int npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - noPadBytes - 1; + defaultOffset += offset; + gotoSet.set(defaultOffset); + for (int j = 0; j < npairs; j++) { // int match = bytes.readInt(); - bytes.readInt(); - index = offset + bytes.readInt(); - gotoSet.set(index); - } + bytes.readInt(); + index = offset + bytes.readInt(); + gotoSet.set(index); } - break; - case Const.GOTO: - case Const.IFEQ: - case Const.IFGE: - case Const.IFGT: - case Const.IFLE: - case Const.IFLT: - case Const.IFNE: - case Const.IFNONNULL: - case Const.IFNULL: - case Const.IF_ACMPEQ: - case Const.IF_ACMPNE: - case Const.IF_ICMPEQ: - case Const.IF_ICMPGE: - case Const.IF_ICMPGT: - case Const.IF_ICMPLE: - case Const.IF_ICMPLT: - case Const.IF_ICMPNE: - case Const.JSR: - //bytes.readByte(); // Skip already read byte - index = bytes.getIndex() + bytes.readShort() - 1; - gotoSet.set(index); - break; - case Const.GOTO_W: - case Const.JSR_W: - //bytes.readByte(); // Skip already read byte - index = bytes.getIndex() + bytes.readInt() - 1; - gotoSet.set(index); - break; - default: - bytes.unreadByte(); - codeToHTML(bytes, 0); // Ignore output + } + break; + case Const.GOTO: + case Const.IFEQ: + case Const.IFGE: + case Const.IFGT: + case Const.IFLE: + case Const.IFLT: + case Const.IFNE: + case Const.IFNONNULL: + case Const.IFNULL: + case Const.IF_ACMPEQ: + case Const.IF_ACMPNE: + case Const.IF_ICMPEQ: + case Const.IF_ICMPGE: + case Const.IF_ICMPGT: + case Const.IF_ICMPLE: + case Const.IF_ICMPLT: + case Const.IF_ICMPNE: + case Const.JSR: + // bytes.readByte(); // Skip already read byte + index = bytes.getIndex() + bytes.readShort() - 1; + gotoSet.set(index); + break; + case Const.GOTO_W: + case Const.JSR_W: + // bytes.readByte(); // Skip already read byte + index = bytes.getIndex() + bytes.readInt() - 1; + gotoSet.set(index); + break; + default: + bytes.unreadByte(); + codeToHTML(bytes, 0); // Ignore output } } } - /** * Write a single method with the byte code associated with it. */ - private void writeMethod( final Method method, final int method_number ) throws IOException { + private void writeMethod(final Method method, final int methodNumber) throws IOException { // Get raw signature final String signature = method.getSignature(); // Get array of strings containing the argument types @@ -505,84 +487,79 @@ final String type = Utility.methodSignatureReturnType(signature, false); // Get method name final String name = method.getName(); - final String html_name = Class2HTML.toHTML(name); + final String htmlName = Class2HTML.toHTML(name); // Get method's access flags String access = Utility.accessToString(method.getAccessFlags()); access = Utility.replace(access, " ", " "); // Get the method's attributes, the Code Attribute in particular final Attribute[] attributes = method.getAttributes(); - file.print("

    " + access + " " + "" + Class2HTML.referenceType(type) + " " - + html_name + "("); + printWriter.print("

    " + access + " " + "" + Class2HTML.referenceType(type) + + " " + htmlName + "("); for (int i = 0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); + printWriter.print(Class2HTML.referenceType(args[i])); if (i < args.length - 1) { - file.print(", "); + printWriter.print(", "); } } - file.println(")

    "); + printWriter.println(")

    "); Code c = null; byte[] code = null; if (attributes.length > 0) { - file.print("

    Attributes

      \n"); + printWriter.print("

      Attributes

        \n"); for (int i = 0; i < attributes.length; i++) { byte tag = attributes[i].getTag(); if (tag != Const.ATTR_UNKNOWN) { - file.print("
      • " - + Const.getAttributeName(tag) + "
      • \n"); + printWriter.print("
      • " + + Const.getAttributeName(tag) + "
      • \n"); } else { - file.print("
      • " + attributes[i] + "
      • "); + printWriter.print("
      • " + attributes[i] + "
      • "); } if (tag == Const.ATTR_CODE) { c = (Code) attributes[i]; final Attribute[] attributes2 = c.getAttributes(); code = c.getCode(); - file.print(""); } } - file.println("
      "); + printWriter.println("
    "); } if (code != null) { // No code, an abstract method, e.g. - //System.out.println(name + "\n" + Utility.codeToString(code, constantPool, 0, -1)); + // System.out.println(name + "\n" + Utility.codeToString(code, constantPool, 0, -1)); // Print the byte code try (ByteSequence stream = new ByteSequence(code)) { stream.mark(stream.available()); findGotos(stream, c); stream.reset(); - file.println("" - + ""); - for (; stream.available() > 0;) { + printWriter.println("
    Byte
    offset
    InstructionArgument
    " + ""); + while (stream.available() > 0) { final int offset = stream.getIndex(); - final String str = codeToHTML(stream, method_number); + final String str = codeToHTML(stream, methodNumber); String anchor = ""; /* - * Set an anchor mark if this line is targetted by a goto, jsr, etc. Defining an anchor for every - * line is very inefficient! + * Set an anchor mark if this line is targetted by a goto, jsr, etc. Defining an anchor for every line is very + * inefficient! */ if (gotoSet.get(offset)) { - anchor = ""; + anchor = ""; } String anchor2; if (stream.getIndex() == code.length) { - anchor2 = "" + offset + ""; + anchor2 = "" + offset + ""; } else { anchor2 = "" + offset; } - file.println(""); + printWriter.println(""); } } // Mark last line, may be targetted from Attributes window - file.println(""); - file.println("
    Byte
    offset
    InstructionArgument
    " + anchor2 + "" + anchor + str + "
    " + anchor2 + "" + anchor + str + "
    "); + printWriter.println(" "); + printWriter.println(""); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ConstantHTML.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,9 +21,10 @@ package com.sun.org.apache.bcel.internal.util; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.FileNotFoundException; import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.Constant; @@ -39,198 +40,164 @@ /** * Convert constant pool into HTML file. - * - * */ final class ConstantHTML { private final String className; // name of current class private final String classPackage; // name of package private final ConstantPool constantPool; // reference to constant pool - private final PrintWriter file; // file to write to + private final PrintWriter printWriter; // file to write to private final String[] constantRef; // String to return for cp[i] private final Constant[] constants; // The constants in the cp private final Method[] methods; - - ConstantHTML(final String dir, final String class_name, final String class_package, final Method[] methods, - final ConstantPool constant_pool) throws IOException { - this.className = class_name; - this.classPackage = class_package; - this.constantPool = constant_pool; + ConstantHTML(final String dir, final String className, final String classPackage, final Method[] methods, final ConstantPool constantPool, + final Charset charset) throws FileNotFoundException, UnsupportedEncodingException { + this.className = className; + this.classPackage = classPackage; + this.constantPool = constantPool; this.methods = methods; - constants = constant_pool.getConstantPool(); - file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); - constantRef = new String[constants.length]; - constantRef[0] = "<unknown>"; - file.println(""); - // Loop through constants, constants[0] is reserved - for (int i = 1; i < constants.length; i++) { - if (i % 2 == 0) { - file.print("
    "); - } else { - file.print("
    "); - } - if (constants[i] != null) { - writeConstant(i); + this.constants = constantPool.getConstantPool(); + try (PrintWriter newPrintWriter = new PrintWriter(dir + className + "_cp.html", charset.name())) { + printWriter = newPrintWriter; + constantRef = new String[constants.length]; + constantRef[0] = "<unknown>"; + printWriter.print(""); + printWriter.println(""); + // Loop through constants, constants[0] is reserved + for (int i = 1; i < constants.length; i++) { + if (i % 2 == 0) { + printWriter.print("\n"); } - file.print("\n"); + printWriter.println("
    "); + } else { + printWriter.print("
    "); + } + if (constants[i] != null) { + writeConstant(i); + } + printWriter.print("
    "); } - file.println("
    "); - file.close(); } + private int getMethodNumber(final String str) { + for (int i = 0; i < methods.length; i++) { + final String cmp = methods[i].getName() + methods[i].getSignature(); + if (cmp.equals(str)) { + return i; + } + } + return -1; + } - String referenceConstant( final int index ) { + String referenceConstant(final int index) { return constantRef[index]; } - - private void writeConstant( final int index ) { + private void writeConstant(final int index) { final byte tag = constants[index].getTag(); - int class_index; - int name_index; + int classIndex; + int nameIndex; String ref; // The header is always the same - file.println("

    " + index + " " + Const.getConstantName(tag) - + "

    "); - /* For every constant type get the needed parameters and print them appropiately + printWriter.println("

    " + index + " " + Const.getConstantName(tag) + "

    "); + /* + * For every constant type get the needed parameters and print them appropriately */ switch (tag) { - case Const.CONSTANT_InterfaceMethodref: - case Const.CONSTANT_Methodref: - // Get class_index and name_and_type_index, depending on type - if (tag == Const.CONSTANT_Methodref) { - final ConstantMethodref c = (ConstantMethodref) constantPool.getConstant(index, - Const.CONSTANT_Methodref); - class_index = c.getClassIndex(); - name_index = c.getNameAndTypeIndex(); - } else { - final ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constantPool - .getConstant(index, Const.CONSTANT_InterfaceMethodref); - class_index = c1.getClassIndex(); - name_index = c1.getNameAndTypeIndex(); - } - // Get method name and its class - final String method_name = constantPool.constantToString(name_index, - Const.CONSTANT_NameAndType); - final String html_method_name = Class2HTML.toHTML(method_name); - // Partially compacted class name, i.e., / -> . - final String method_class = constantPool.constantToString(class_index, Const.CONSTANT_Class); - String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(short_method_class, classPackage - + ".", true); // Remove class package prefix - // Get method signature - final ConstantNameAndType c2 = (ConstantNameAndType) constantPool.getConstant( - name_index, Const.CONSTANT_NameAndType); - final String signature = constantPool.constantToString(c2.getSignatureIndex(), - Const.CONSTANT_Utf8); - // Get array of strings containing the argument types - final String[] args = Utility.methodSignatureArgumentTypes(signature, false); - // Get return type string - final String type = Utility.methodSignatureReturnType(signature, false); - final String ret_type = Class2HTML.referenceType(type); - final StringBuilder buf = new StringBuilder("("); - for (int i = 0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - if (i < args.length - 1) { - buf.append(", "); - } - } - buf.append(")"); - final String arg_types = buf.toString(); - if (method_class.equals(className)) { - ref = "" - + html_method_name + ""; - } else { - ref = "" - + short_method_class + "." + html_method_name; - } - constantRef[index] = ret_type + " " + short_method_class - + "." + html_method_name + " " + arg_types; - file.println("

    " + ret_type + " " + ref + arg_types - + " \n

    "); - break; - case Const.CONSTANT_Fieldref: - // Get class_index and name_and_type_index - final ConstantFieldref c3 = (ConstantFieldref) constantPool.getConstant(index, - Const.CONSTANT_Fieldref); - class_index = c3.getClassIndex(); - name_index = c3.getNameAndTypeIndex(); - // Get method name and its class (compacted) - final String field_class = constantPool.constantToString(class_index, Const.CONSTANT_Class); - String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. - short_field_class = Utility.compactClassName(short_field_class, - classPackage + ".", true); // Remove class package prefix - final String field_name = constantPool - .constantToString(name_index, Const.CONSTANT_NameAndType); - if (field_class.equals(className)) { - ref = "" + field_name + ""; - } else { - ref = "" + short_field_class - + "." + field_name + "\n"; + case Const.CONSTANT_InterfaceMethodref: + case Const.CONSTANT_Methodref: + // Get class_index and name_and_type_index, depending on type + if (tag == Const.CONSTANT_Methodref) { + final ConstantMethodref c = constantPool.getConstant(index, Const.CONSTANT_Methodref, ConstantMethodref.class); + classIndex = c.getClassIndex(); + nameIndex = c.getNameAndTypeIndex(); + } else { + final ConstantInterfaceMethodref c1 = constantPool.getConstant(index, Const.CONSTANT_InterfaceMethodref, ConstantInterfaceMethodref.class); + classIndex = c1.getClassIndex(); + nameIndex = c1.getNameAndTypeIndex(); + } + // Get method name and its class + final String methodName = constantPool.constantToString(nameIndex, Const.CONSTANT_NameAndType); + final String htmlMethodName = Class2HTML.toHTML(methodName); + // Partially compacted class name, i.e., / -> . + final String methodClass = constantPool.constantToString(classIndex, Const.CONSTANT_Class); + String shortMethodClass = Utility.compactClassName(methodClass); // I.e., remove java.lang. + shortMethodClass = Utility.compactClassName(shortMethodClass, classPackage + ".", true); // Remove class package prefix + // Get method signature + final ConstantNameAndType c2 = constantPool.getConstant(nameIndex, Const.CONSTANT_NameAndType, ConstantNameAndType.class); + final String signature = constantPool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8); + // Get array of strings containing the argument types + final String[] args = Utility.methodSignatureArgumentTypes(signature, false); + // Get return type string + final String type = Utility.methodSignatureReturnType(signature, false); + final String retType = Class2HTML.referenceType(type); + final StringBuilder buf = new StringBuilder("("); + for (int i = 0; i < args.length; i++) { + buf.append(Class2HTML.referenceType(args[i])); + if (i < args.length - 1) { + buf.append(", "); } - constantRef[index] = "" + short_field_class + "." - + field_name + ""; - file.println("

    " + ref + "
    \n" + "

    "); - break; - case Const.CONSTANT_Class: - final ConstantClass c4 = (ConstantClass) constantPool.getConstant(index, Const.CONSTANT_Class); - name_index = c4.getNameIndex(); - final String class_name2 = constantPool.constantToString(index, tag); // / -> . - String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. - short_class_name = Utility.compactClassName(short_class_name, classPackage + ".", - true); // Remove class package prefix - ref = "" + short_class_name - + ""; - constantRef[index] = "" + short_class_name + ""; - file.println("

    " + ref + "

    \n"); - break; - case Const.CONSTANT_String: - final ConstantString c5 = (ConstantString) constantPool.getConstant(index, - Const.CONSTANT_String); - name_index = c5.getStringIndex(); - final String str = Class2HTML.toHTML(constantPool.constantToString(index, tag)); - file.println("

    " + str + "

    \n"); - break; - case Const.CONSTANT_NameAndType: - final ConstantNameAndType c6 = (ConstantNameAndType) constantPool.getConstant(index, - Const.CONSTANT_NameAndType); - name_index = c6.getNameIndex(); - final int signature_index = c6.getSignatureIndex(); - file.println("

    " - + Class2HTML.toHTML(constantPool.constantToString(index, tag)) - + "

    \n"); - break; - default: - file.println("

    " + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "\n"); - } // switch - } - - - private int getMethodNumber( final String str ) { - for (int i = 0; i < methods.length; i++) { - final String cmp = methods[i].getName() + methods[i].getSignature(); - if (cmp.equals(str)) { - return i; } - } - return -1; + buf.append(")"); + final String argTypes = buf.toString(); + if (methodClass.equals(className)) { + ref = "" + htmlMethodName + ""; + } else { + ref = "" + shortMethodClass + "." + htmlMethodName; + } + constantRef[index] = retType + " " + shortMethodClass + + "." + htmlMethodName + " " + argTypes; + printWriter.println("

    " + retType + " " + ref + argTypes + " \n

    "); + break; + case Const.CONSTANT_Fieldref: + // Get class_index and name_and_type_index + final ConstantFieldref c3 = constantPool.getConstant(index, Const.CONSTANT_Fieldref, ConstantFieldref.class); + classIndex = c3.getClassIndex(); + nameIndex = c3.getNameAndTypeIndex(); + // Get method name and its class (compacted) + final String fieldClass = constantPool.constantToString(classIndex, Const.CONSTANT_Class); + String shortFieldClass = Utility.compactClassName(fieldClass); // I.e., remove java.lang. + shortFieldClass = Utility.compactClassName(shortFieldClass, classPackage + ".", true); // Remove class package prefix + final String fieldName = constantPool.constantToString(nameIndex, Const.CONSTANT_NameAndType); + if (fieldClass.equals(className)) { + ref = "" + fieldName + ""; + } else { + ref = "" + shortFieldClass + "." + fieldName + "\n"; + } + constantRef[index] = "" + shortFieldClass + "." + fieldName + ""; + printWriter.println("

    " + ref + "
    \n" + "

    "); + break; + case Const.CONSTANT_Class: + final ConstantClass c4 = constantPool.getConstant(index, Const.CONSTANT_Class, ConstantClass.class); + nameIndex = c4.getNameIndex(); + final String className2 = constantPool.constantToString(index, tag); // / -> . + String shortClassName = Utility.compactClassName(className2); // I.e., remove java.lang. + shortClassName = Utility.compactClassName(shortClassName, classPackage + ".", true); // Remove class package prefix + ref = "" + shortClassName + ""; + constantRef[index] = "" + shortClassName + ""; + printWriter.println("

    " + ref + "

    \n"); + break; + case Const.CONSTANT_String: + final ConstantString c5 = constantPool.getConstant(index, Const.CONSTANT_String, ConstantString.class); + nameIndex = c5.getStringIndex(); + final String str = Class2HTML.toHTML(constantPool.constantToString(index, tag)); + printWriter.println("

    " + str + "

    \n"); + break; + case Const.CONSTANT_NameAndType: + final ConstantNameAndType c6 = constantPool.getConstant(index, Const.CONSTANT_NameAndType, ConstantNameAndType.class); + nameIndex = c6.getNameIndex(); + final int signatureIndex = c6.getSignatureIndex(); + printWriter.println("

    " + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "

    \n"); + break; + default: + printWriter.println("

    " + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "\n"); + } // switch } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java 2023-10-06 05:33:33.000000000 +0000 @@ -20,11 +20,8 @@ package com.sun.org.apache.bcel.internal.util; -import com.sun.org.apache.bcel.internal.Const; -import com.sun.org.apache.bcel.internal.generic.ClassGenException; -import com.sun.org.apache.bcel.internal.generic.InstructionHandle; -import com.sun.org.apache.bcel.internal.generic.InstructionList; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -33,16 +30,18 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.sun.org.apache.bcel.internal.Const; +import com.sun.org.apache.bcel.internal.generic.ClassGenException; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.generic.InstructionList; + /** - * InstructionFinder is a tool to search for given instructions patterns, i.e., - * match sequences of instructions in an instruction list via regular - * expressions. This can be used, e.g., in order to implement a peep hole - * optimizer that looks for code patterns and replaces them with faster - * equivalents. + * InstructionFinder is a tool to search for given instructions patterns, i.e., match sequences of instructions in an + * instruction list via regular expressions. This can be used, e.g., in order to implement a peep hole optimizer that + * looks for code patterns and replaces them with faster equivalents. * *

    - * This class internally uses the java.util.regex - * package to search for regular expressions. + * This class internally uses the java.util.regex package to search for regular expressions. * * A typical application would look like this: * @@ -68,73 +67,116 @@ */ public class InstructionFinder { - private static final int OFFSET = 32767; // char + OFFSET is outside of LATIN-1 - private static final int NO_OPCODES = 256; // Potential number, some are not used - private static final Map map = new HashMap<>(); - private final InstructionList il; - private String ilString; // instruction list as string - private InstructionHandle[] handles; // map instruction - - - // list to array /** - * @param il - * instruction list to search for given patterns + * Code patterns found may be checked using an additional user-defined constraint object whether they really match the + * needed criterion. I.e., check constraints that can not expressed with regular expressions. + * */ - public InstructionFinder(final InstructionList il) { - this.il = il; - reread(); - } - + public interface CodeConstraint { - /** - * Reread the instruction list, e.g., after you've altered the list upon a - * match. - */ - public final void reread() { - final int size = il.getLength(); - final char[] buf = new char[size]; // Create a string with length equal to il length - handles = il.getInstructionHandles(); - // Map opcodes to characters - for (int i = 0; i < size; i++) { - buf[i] = makeChar(handles[i].getInstruction().getOpcode()); - } - ilString = new String(buf); + /** + * @param match array of instructions matching the requested pattern + * @return true if the matched area is really useful + */ + boolean checkCode(InstructionHandle[] match); } + private static final int OFFSET = 32767; // char + OFFSET is outside of LATIN-1 + private static final int NO_OPCODES = 256; // Potential number, some are not used + private static final Map map = new HashMap<>(); - /** - * Map symbolic instruction names like "getfield" to a single character. - * - * @param pattern - * instruction pattern in lower case - * @return encoded string for a pattern such as "BranchInstruction". - */ - private static String mapName( final String pattern ) { - final String result = map.get(pattern); - if (result != null) { - return result; - } + // Initialize pattern map + static { + map.put("arithmeticinstruction", + "(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); + map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial|invokedynamic)"); + map.put("arrayinstruction", + "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); + map.put("gotoinstruction", "(goto|goto_w)"); + map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); + map.put("localvariableinstruction", "(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); + map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); + map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); + map.put("cpinstruction", + "(ldc2_w|invokeinterface|invokedynamic|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); + map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); + map.put("branchinstruction", + "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); + map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); + map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); + map.put("select", "(tableswitch|lookupswitch)"); + map.put("ifinstruction", + "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); + map.put("jsrinstruction", "(jsr|jsr_w)"); + map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); + map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); + map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); + map.put("typedinstruction", + "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); + map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); + map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); + map.put("indexedinstruction", + "(lload|lstore|fload|ldc2_w|invokeinterface|invokedynamic|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); + map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); + map.put("stackproducer", + "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|invokedynamic|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); + map.put("stackconsumer", + "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); + map.put("exceptionthrower", + "(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|invokedynamic|ldc|invokestatic|daload)"); + map.put("loadclass", + "(multianewarray|invokeinterface|invokedynamic|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); + map.put("instructiontargeter", + "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); + // Some aliases + map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); + map.put("if_acmp", "(if_acmpeq|if_acmpne)"); + map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); + // Precompile some aliases first + map.put("iconst", precompile(Const.ICONST_0, Const.ICONST_5, Const.ICONST_M1)); + map.put("lconst", new String(new char[] {'(', makeChar(Const.LCONST_0), '|', makeChar(Const.LCONST_1), ')'})); + map.put("dconst", new String(new char[] {'(', makeChar(Const.DCONST_0), '|', makeChar(Const.DCONST_1), ')'})); + map.put("fconst", new String(new char[] {'(', makeChar(Const.FCONST_0), '|', makeChar(Const.FCONST_1), '|', makeChar(Const.FCONST_2), ')'})); + map.put("lload", precompile(Const.LLOAD_0, Const.LLOAD_3, Const.LLOAD)); + map.put("iload", precompile(Const.ILOAD_0, Const.ILOAD_3, Const.ILOAD)); + map.put("dload", precompile(Const.DLOAD_0, Const.DLOAD_3, Const.DLOAD)); + map.put("fload", precompile(Const.FLOAD_0, Const.FLOAD_3, Const.FLOAD)); + map.put("aload", precompile(Const.ALOAD_0, Const.ALOAD_3, Const.ALOAD)); + map.put("lstore", precompile(Const.LSTORE_0, Const.LSTORE_3, Const.LSTORE)); + map.put("istore", precompile(Const.ISTORE_0, Const.ISTORE_3, Const.ISTORE)); + map.put("dstore", precompile(Const.DSTORE_0, Const.DSTORE_3, Const.DSTORE)); + map.put("fstore", precompile(Const.FSTORE_0, Const.FSTORE_3, Const.FSTORE)); + map.put("astore", precompile(Const.ASTORE_0, Const.ASTORE_3, Const.ASTORE)); + // Compile strings + map.forEach((key, value) -> { + final char ch = value.charAt(1); // Omit already precompiled patterns + if (ch < OFFSET) { + map.put(key, compilePattern(value)); // precompile all patterns + } + }); + // Add instruction alias to match anything + final StringBuilder buf = new StringBuilder("("); for (short i = 0; i < NO_OPCODES; i++) { - if (pattern.equals(Const.getOpcodeName(i))) { - return "" + makeChar(i); + if (Const.getNoOfOperands(i) != Const.UNDEFINED) { // Not an invalid opcode + buf.append(makeChar(i)); + if (i < NO_OPCODES - 1) { + buf.append('|'); + } } } - throw new IllegalArgumentException("Instruction unknown: " + pattern); + buf.append(')'); + map.put("instruction", buf.toString()); } - /** - * Replace symbolic names of instructions with the appropiate character and - * remove all white space from string. Meta characters such as +, * are - * ignored. + * Replace symbolic names of instructions with the appropriate character and remove all white space from string. Meta + * characters such as +, * are ignored. * - * @param pattern - * The pattern to compile + * @param pattern The pattern to compile * @return translated regular expression string */ - private static String compilePattern( final String pattern ) { - //Bug: BCEL-77 - Instructions are assumed to be english, to avoid odd Locale issues + private static String compilePattern(final String pattern) { + // Bug: BCEL-77 - Instructions are assumed to be english, to avoid odd Locale issues final String lower = pattern.toLowerCase(Locale.ENGLISH); final StringBuilder buf = new StringBuilder(); final int size = pattern.length(); @@ -144,11 +186,10 @@ final StringBuilder name = new StringBuilder(); while ((Character.isLetterOrDigit(ch) || ch == '_') && i < size) { name.append(ch); - if (++i < size) { - ch = lower.charAt(i); - } else { + if (++i >= size) { break; } + ch = lower.charAt(i); } i--; buf.append(mapName(name.toString())); @@ -159,245 +200,172 @@ return buf.toString(); } - /** - * @return the matched piece of code as an array of instruction (handles) + * Convert opcode number to char. */ - private InstructionHandle[] getMatch( final int matched_from, final int match_length ) { - final InstructionHandle[] match = new InstructionHandle[match_length]; - System.arraycopy(handles, matched_from, match, 0, match_length); - return match; + private static char makeChar(final short opcode) { + return (char) (opcode + OFFSET); } - /** - * Search for the given pattern in the instruction list. You can search for - * any valid opcode via its symbolic name, e.g. "istore". You can also use a - * super class or an interface name to match a whole set of instructions, e.g. - * "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all - * "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp" - * for "if_icmpxx", "if_acmp" for "if_acmpxx". - * - * Consecutive instruction names must be separated by white space which will - * be removed during the compilation of the pattern. - * - * For the rest the usual pattern matching rules for regular expressions - * apply. - *

    - * Example pattern: - * - *

    -     * search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
    -     * 
    + * Map symbolic instruction names like "getfield" to a single character. * - *

    - * If you alter the instruction list upon a match such that other matching - * areas are affected, you should call reread() to update the finder and call - * search() again, because the matches are cached. - * - * @param pattern - * the instruction pattern to search for, where case is ignored - * @param from - * where to start the search in the instruction list - * @param constraint - * optional CodeConstraint to check the found code pattern for - * user-defined constraints - * @return iterator of matches where e.nextElement() returns an array of - * instruction handles describing the matched area + * @param pattern instruction pattern in lower case + * @return encoded string for a pattern such as "BranchInstruction". */ - public final Iterator search( final String pattern, - final InstructionHandle from, final CodeConstraint constraint ) { - final String search = compilePattern(pattern); - int start = -1; - for (int i = 0; i < handles.length; i++) { - if (handles[i] == from) { - start = i; // Where to start search from (index) - break; - } - } - if (start == -1) { - throw new ClassGenException("Instruction handle " + from - + " not found in instruction list."); + private static String mapName(final String pattern) { + final String result = map.get(pattern); + if (result != null) { + return result; } - final Pattern regex = Pattern.compile(search); - final List matches = new ArrayList<>(); - final Matcher matcher = regex.matcher(ilString); - while (start < ilString.length() && matcher.find(start)) { - final int startExpr = matcher.start(); - final int endExpr = matcher.end(); - final int lenExpr = endExpr - startExpr; - final InstructionHandle[] match = getMatch(startExpr, lenExpr); - if ((constraint == null) || constraint.checkCode(match)) { - matches.add(match); + for (short i = 0; i < NO_OPCODES; i++) { + if (pattern.equals(Const.getOpcodeName(i))) { + return String.valueOf(makeChar(i)); } - start = endExpr; } - return matches.iterator(); + throw new IllegalArgumentException("Instruction unknown: " + pattern); + } + + private static String precompile(final short from, final short to, final short extra) { + final StringBuilder buf = new StringBuilder("("); + for (short i = from; i <= to; i++) { + buf.append(makeChar(i)); + buf.append('|'); + } + buf.append(makeChar(extra)); + buf.append(")"); + return buf.toString(); } + private final InstructionList il; + + private String ilString; // instruction list as string + + private InstructionHandle[] handles; // map instruction + // list to array /** - * Start search beginning from the start of the given instruction list. - * - * @param pattern - * the instruction pattern to search for, where case is ignored - * @return iterator of matches where e.nextElement() returns an array of - * instruction handles describing the matched area + * @param il instruction list to search for given patterns */ - public final Iterator search( final String pattern ) { - return search(pattern, il.getStart(), null); + public InstructionFinder(final InstructionList il) { + this.il = il; + reread(); } - /** - * Start search beginning from `from'. - * - * @param pattern - * the instruction pattern to search for, where case is ignored - * @param from - * where to start the search in the instruction list - * @return iterator of matches where e.nextElement() returns an array of - * instruction handles describing the matched area + * @return the inquired instruction list */ - public final Iterator search( final String pattern, - final InstructionHandle from ) { - return search(pattern, from, null); + public final InstructionList getInstructionList() { + return il; } - /** - * Start search beginning from the start of the given instruction list. Check - * found matches with the constraint object. - * - * @param pattern - * the instruction pattern to search for, case is ignored - * @param constraint - * constraints to be checked on matching code - * @return instruction handle or `null' if the match failed + * @return the matched piece of code as an array of instruction (handles) */ - public final Iterator search( final String pattern, - final CodeConstraint constraint ) { - return search(pattern, il.getStart(), constraint); + private InstructionHandle[] getMatch(final int matchedFrom, final int matchLength) { + return Arrays.copyOfRange(handles, matchedFrom, matchedFrom + matchLength); } - /** - * Convert opcode number to char. + * Reread the instruction list, e.g., after you've altered the list upon a match. */ - private static char makeChar( final short opcode ) { - return (char) (opcode + OFFSET); + public final void reread() { + final int size = il.getLength(); + final char[] buf = new char[size]; // Create a string with length equal to il length + handles = il.getInstructionHandles(); + // Map opcodes to characters + for (int i = 0; i < size; i++) { + buf[i] = makeChar(handles[i].getInstruction().getOpcode()); + } + ilString = new String(buf); } - /** - * @return the inquired instruction list + * Start search beginning from the start of the given instruction list. + * + * @param pattern the instruction pattern to search for, where case is ignored + * @return iterator of matches where e.nextElement() returns an array of instruction handles describing the matched area */ - public final InstructionList getInstructionList() { - return il; + public final Iterator search(final String pattern) { + return search(pattern, il.getStart(), null); } /** - * Code patterns found may be checked using an additional user-defined - * constraint object whether they really match the needed criterion. I.e., - * check constraints that can not expressed with regular expressions. + * Start search beginning from the start of the given instruction list. Check found matches with the constraint object. * + * @param pattern the instruction pattern to search for, case is ignored + * @param constraint constraints to be checked on matching code + * @return instruction handle or 'null' if the match failed */ - public interface CodeConstraint { + public final Iterator search(final String pattern, final CodeConstraint constraint) { + return search(pattern, il.getStart(), constraint); + } - /** - * @param match - * array of instructions matching the requested pattern - * @return true if the matched area is really useful - */ - boolean checkCode( InstructionHandle[] match ); + /** + * Start search beginning from 'from'. + * + * @param pattern the instruction pattern to search for, where case is ignored + * @param from where to start the search in the instruction list + * @return iterator of matches where e.nextElement() returns an array of instruction handles describing the matched area + */ + public final Iterator search(final String pattern, final InstructionHandle from) { + return search(pattern, from, null); } - // Initialize pattern map - static { - map.put("arithmeticinstruction","(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); - map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial|invokedynamic)"); - map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); - map.put("gotoinstruction", "(goto|goto_w)"); - map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); - map.put("localvariableinstruction","(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); - map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); - map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); - map.put("cpinstruction", "(ldc2_w|invokeinterface|invokedynamic|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); - map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); - map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); - map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); - map.put("select", "(tableswitch|lookupswitch)"); - map.put("ifinstruction", "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); - map.put("jsrinstruction", "(jsr|jsr_w)"); - map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); - map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); - map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); - map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); - map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); - map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); - map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|invokedynamic|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); - map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); - map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|invokedynamic|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); - map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); - map.put("exceptionthrower","(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|invokedynamic|ldc|invokestatic|daload)"); - map.put("loadclass", "(multianewarray|invokeinterface|invokedynamic|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); - map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - // Some aliases - map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); - map.put("if_acmp", "(if_acmpeq|if_acmpne)"); - map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); - // Precompile some aliases first - map.put("iconst", precompile(Const.ICONST_0, Const.ICONST_5, Const.ICONST_M1)); - map.put("lconst", new String(new char[] { '(', makeChar(Const.LCONST_0), '|', makeChar(Const.LCONST_1), ')' })); - map.put("dconst", new String(new char[] { '(', makeChar(Const.DCONST_0), '|', makeChar(Const.DCONST_1), ')' })); - map.put("fconst", new String(new char[] { '(', makeChar(Const.FCONST_0), '|', makeChar(Const.FCONST_1), '|', makeChar(Const.FCONST_2), ')' })); - map.put("lload", precompile(Const.LLOAD_0, Const.LLOAD_3, Const.LLOAD)); - map.put("iload", precompile(Const.ILOAD_0, Const.ILOAD_3, Const.ILOAD)); - map.put("dload", precompile(Const.DLOAD_0, Const.DLOAD_3, Const.DLOAD)); - map.put("fload", precompile(Const.FLOAD_0, Const.FLOAD_3, Const.FLOAD)); - map.put("aload", precompile(Const.ALOAD_0, Const.ALOAD_3, Const.ALOAD)); - map.put("lstore", precompile(Const.LSTORE_0, Const.LSTORE_3, Const.LSTORE)); - map.put("istore", precompile(Const.ISTORE_0, Const.ISTORE_3, Const.ISTORE)); - map.put("dstore", precompile(Const.DSTORE_0, Const.DSTORE_3, Const.DSTORE)); - map.put("fstore", precompile(Const.FSTORE_0, Const.FSTORE_3, Const.FSTORE)); - map.put("astore", precompile(Const.ASTORE_0, Const.ASTORE_3, Const.ASTORE)); - // Compile strings - for (final Map.Entry entry : map.entrySet()) { - final String key = entry.getKey(); - final String value = entry.getValue(); - final char ch = value.charAt(1); // Omit already precompiled patterns - if (ch < OFFSET) { - map.put(key, compilePattern(value)); // precompile all patterns + /** + * Search for the given pattern in the instruction list. You can search for any valid opcode via its symbolic name, e.g. + * "istore". You can also use a super class or an interface name to match a whole set of instructions, e.g. + * "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all "istore_x" instructions. Additional + * aliases are "if" for "ifxx", "if_icmp" for "if_icmpxx", "if_acmp" for "if_acmpxx". + * + * Consecutive instruction names must be separated by white space which will be removed during the compilation of the + * pattern. + * + * For the rest the usual pattern matching rules for regular expressions apply. + *

    + * Example pattern: + * + *

    +     * search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
    +     * 
    + * + *

    + * If you alter the instruction list upon a match such that other matching areas are affected, you should call reread() + * to update the finder and call search() again, because the matches are cached. + * + * @param pattern the instruction pattern to search for, where case is ignored + * @param from where to start the search in the instruction list + * @param constraint optional CodeConstraint to check the found code pattern for user-defined constraints + * @return iterator of matches where e.nextElement() returns an array of instruction handles describing the matched area + */ + public final Iterator search(final String pattern, final InstructionHandle from, final CodeConstraint constraint) { + final String search = compilePattern(pattern); + int start = -1; + for (int i = 0; i < handles.length; i++) { + if (handles[i] == from) { + start = i; // Where to start search from (index) + break; } } - // Add instruction alias to match anything - final StringBuilder buf = new StringBuilder("("); - for (short i = 0; i < NO_OPCODES; i++) { - if (Const.getNoOfOperands(i) != Const.UNDEFINED) { // Not an invalid opcode - buf.append(makeChar(i)); - if (i < NO_OPCODES - 1) { - buf.append('|'); - } - } + if (start == -1) { + throw new ClassGenException("Instruction handle " + from + " not found in instruction list."); } - buf.append(')'); - map.put("instruction", buf.toString()); - } - - - private static String precompile( final short from, final short to, final short extra ) { - final StringBuilder buf = new StringBuilder("("); - for (short i = from; i <= to; i++) { - buf.append(makeChar(i)); - buf.append('|'); + final Pattern regex = Pattern.compile(search); + final List matches = new ArrayList<>(); + final Matcher matcher = regex.matcher(ilString); + while (start < ilString.length() && matcher.find(start)) { + final int startExpr = matcher.start(); + final int endExpr = matcher.end(); + final int lenExpr = endExpr - startExpr; + final InstructionHandle[] match = getMatch(startExpr, lenExpr); + if (constraint == null || constraint.checkCode(match)) { + matches.add(match); + } + start = endExpr; } - buf.append(makeChar(extra)); - buf.append(")"); - return buf.toString(); + return matches.iterator(); } - /* * Internal debugging routines. */ @@ -405,7 +373,6 @@ // return pattern2string(pattern, true); // } - // private static final String pattern2string( String pattern, boolean make_string ) { // StringBuffer buf = new StringBuffer(); // for (int i = 0; i < pattern.length(); i++) { diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/MethodHTML.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,14 +21,14 @@ package com.sun.org.apache.bcel.internal.util; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.FileNotFoundException; import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; import com.sun.org.apache.bcel.internal.Const; import com.sun.org.apache.bcel.internal.classfile.Attribute; import com.sun.org.apache.bcel.internal.classfile.Code; -import com.sun.org.apache.bcel.internal.classfile.ConstantValue; import com.sun.org.apache.bcel.internal.classfile.ExceptionTable; import com.sun.org.apache.bcel.internal.classfile.Field; import com.sun.org.apache.bcel.internal.classfile.Method; @@ -36,75 +36,69 @@ /** * Convert methods and fields into HTML file. - * - * */ final class MethodHTML { private final String className; // name of current class - private final PrintWriter file; // file to write to + private final PrintWriter printWriter; // file to write to private final ConstantHTML constantHtml; - private final AttributeHTML attribute_html; + private final AttributeHTML attributeHtml; - - MethodHTML(final String dir, final String class_name, final Method[] methods, final Field[] fields, - final ConstantHTML constant_html, final AttributeHTML attribute_html) throws IOException { - this.className = class_name; - this.attribute_html = attribute_html; - this.constantHtml = constant_html; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); - file.println(""); - file.println("" - + ""); - for (final Field field : fields) { - writeField(field); - } - file.println("
    Access flagsTypeField name
    "); - file.println("" - + "" - + ""); - for (int i = 0; i < methods.length; i++) { - writeMethod(methods[i], i); + MethodHTML(final String dir, final String className, final Method[] methods, final Field[] fields, final ConstantHTML constantHtml, + final AttributeHTML attributeHtml, final Charset charset) throws FileNotFoundException, UnsupportedEncodingException { + this.className = className; + this.attributeHtml = attributeHtml; + this.constantHtml = constantHtml; + try (PrintWriter newPrintWriter = new PrintWriter(dir + className + "_methods.html", charset.name())) { + printWriter = newPrintWriter; + printWriter.print(""); + printWriter.println("
    Access flagsReturn typeMethod nameArguments
    "); + printWriter.println("" + ""); + for (final Field field : fields) { + writeField(field); + } + printWriter.println("
    Access flagsTypeField name
    "); + printWriter.println("" + + "" + ""); + for (int i = 0; i < methods.length; i++) { + writeMethod(methods[i], i); + } + printWriter.println("
    Access flagsReturn typeMethod nameArguments
    "); } - file.println(""); - file.close(); } - /** * Print field of class. * * @param field field to print - * @throws java.io.IOException */ - private void writeField( final Field field ) throws IOException { + private void writeField(final Field field) { final String type = Utility.signatureToString(field.getSignature()); final String name = field.getName(); String access = Utility.accessToString(field.getAccessFlags()); Attribute[] attributes; access = Utility.replace(access, " ", " "); - file.print("" + access + "\n" - + Class2HTML.referenceType(type) + "" + name - + ""); + printWriter.print("" + access + "\n" + Class2HTML.referenceType(type) + "" + name + ""); attributes = field.getAttributes(); // Write them to the Attributes.html file with anchor "[]" for (int i = 0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], name + "@" + i); + attributeHtml.writeAttribute(attributes[i], name + "@" + i); } for (int i = 0; i < attributes.length; i++) { if (attributes[i].getTag() == Const.ATTR_CONSTANT_VALUE) { // Default value - final String str = ((ConstantValue) attributes[i]).toString(); + final String str = attributes[i].toString(); // Reference attribute in _attributes.html - file.print("= " + str + "\n"); + printWriter.print("= " + str + "\n"); break; } } - file.println(""); + printWriter.println(""); } - - private void writeMethod( final Method method, final int method_number ) { + private void writeMethod(final Method method, final int methodNumber) { // Get raw signature final String signature = method.getSignature(); // Get array of strings containing the argument types @@ -113,48 +107,44 @@ final String type = Utility.methodSignatureReturnType(signature, false); // Get method name final String name = method.getName(); - String html_name; + String htmlName; // Get method's access flags String access = Utility.accessToString(method.getAccessFlags()); // Get the method's attributes, the Code Attribute in particular final Attribute[] attributes = method.getAttributes(); - /* HTML doesn't like names like and spaces are places to break - * lines. Both we don't want... + /* + * HTML doesn't like names like and spaces are places to break lines. Both we don't want... */ access = Utility.replace(access, " ", " "); - html_name = Class2HTML.toHTML(name); - file.print("" + access + ""); - file.print("" + Class2HTML.referenceType(type) + "" + "" + html_name - + "\n("); + htmlName = Class2HTML.toHTML(name); + printWriter.print("" + access + ""); + printWriter.print("" + Class2HTML.referenceType(type) + "" + "" + + htmlName + "\n("); for (int i = 0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); + printWriter.print(Class2HTML.referenceType(args[i])); if (i < args.length - 1) { - file.print(", "); + printWriter.print(", "); } } - file.print(")"); + printWriter.print(")"); // Check for thrown exceptions for (int i = 0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i, - method_number); + attributeHtml.writeAttribute(attributes[i], "method" + methodNumber + "@" + i, methodNumber); final byte tag = attributes[i].getTag(); if (tag == Const.ATTR_EXCEPTIONS) { - file.print("throws"); + printWriter.print("throws"); final int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable(); for (int j = 0; j < exceptions.length; j++) { - file.print(constantHtml.referenceConstant(exceptions[j])); + printWriter.print(constantHtml.referenceConstant(exceptions[j])); if (j < exceptions.length - 1) { - file.print(", "); + printWriter.print(", "); } } - file.println(""); + printWriter.println(""); } else if (tag == Const.ATTR_CODE) { - final Attribute[] c_a = ((Code) attributes[i]).getAttributes(); - for (int j = 0; j < c_a.length; j++) { - attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@" - + j, method_number); + final Attribute[] attributeArray = ((Code) attributes[i]).getAttributes(); + for (int j = 0; j < attributeArray.length; j++) { + attributeHtml.writeAttribute(attributeArray[j], "method" + methodNumber + "@" + i + "@" + j, methodNumber); } } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ModularRuntimeImage.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ModularRuntimeImage.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ModularRuntimeImage.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/ModularRuntimeImage.java 2023-10-06 05:33:33.000000000 +0000 @@ -35,7 +35,6 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -54,28 +53,24 @@ /** * Constructs a default instance. - * - * @throws IOException - * an I/O error occurs accessing the file system */ - public ModularRuntimeImage() throws IOException { + @SuppressWarnings("resource") // See #close() + public ModularRuntimeImage() { this(null, FileSystems.getFileSystem(URI.create("jrt:/"))); } /** * Constructs an instance using the JRT file system implementation from a specific Java Home. * - * @param javaHome - * Path to a Java 9 or greater home. + * @param javaHome Path to a Java 9 or greater home. * - * @throws IOException - * an I/O error occurs accessing the file system + * @throws IOException an I/O error occurs accessing the file system */ public ModularRuntimeImage(final String javaHome) throws IOException { final Map emptyMap = Collections.emptyMap(); final Path jrePath = Paths.get(javaHome); final Path jrtFsPath = jrePath.resolve("lib").resolve("jrt-fs.jar"); - this.classLoader = new URLClassLoader(new URL[] {jrtFsPath.toUri().toURL() }); + this.classLoader = URLClassLoader.newInstance(new URL[] {jrtFsPath.toUri().toURL()}); this.fileSystem = FileSystems.newFileSystem(URI.create("jrt:/"), emptyMap, classLoader); } @@ -94,22 +89,21 @@ } } + public FileSystem getFileSystem() { + return fileSystem; + } + /** * Lists all entries in the given directory. * - * @param dirPath - * directory path. + * @param dirPath directory path. * @return a list of dir entries if an I/O error occurs - * @throws IOException - * an I/O error occurs accessing the file system + * @throws IOException an I/O error occurs accessing the file system */ public List list(final Path dirPath) throws IOException { final List list = new ArrayList<>(); try (DirectoryStream ds = Files.newDirectoryStream(dirPath)) { - final Iterator iterator = ds.iterator(); - while (iterator.hasNext()) { - list.add(iterator.next()); - } + ds.forEach(list::add); } return list; } @@ -117,11 +111,9 @@ /** * Lists all entries in the given directory. * - * @param dirName - * directory path. + * @param dirName directory path. * @return a list of dir entries if an I/O error occurs - * @throws IOException - * an I/O error occurs accessing the file system + * @throws IOException an I/O error occurs accessing the file system */ public List list(final String dirName) throws IOException { return list(fileSystem.getPath(dirName)); @@ -131,8 +123,7 @@ * Lists all modules. * * @return a list of modules - * @throws IOException - * an I/O error occurs accessing the file system + * @throws IOException an I/O error occurs accessing the file system */ public List modules() throws IOException { return list(MODULES_PATH); @@ -142,15 +133,10 @@ * Lists all packages. * * @return a list of modules - * @throws IOException - * an I/O error occurs accessing the file system + * @throws IOException an I/O error occurs accessing the file system */ public List packages() throws IOException { return list(PACKAGES_PATH); } - public FileSystem getFileSystem() { - return fileSystem; - } - } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/Repository.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,42 +22,45 @@ import com.sun.org.apache.bcel.internal.classfile.JavaClass; /** - * Abstract definition of a class repository. Instances may be used - * to load classes from different sources and may be used in the - * Repository.setRepository method. + * Abstract definition of a class repository. Instances may be used to load classes from different sources and may be + * used in the Repository.setRepository method. * - * @see com.sun.org.apache.bcel.internal.Repository - * @LastModified: Jan 2020 + * @see org.apache.bcel.Repository + * @LastModified: Feb 2023 */ public interface Repository { /** - * Stores the provided class under "clazz.getClassName()" + * Clears all entries from cache. */ - void storeClass(JavaClass clazz); + void clear(); /** - * Removes class from repository + * Finds the class with the name provided, if the class isn't there, return NULL. */ - void removeClass(JavaClass clazz); + JavaClass findClass(String className); /** - * Finds the class with the name provided, if the class isn't there, return NULL. + * Finds the JavaClass instance for the given run-time class object. + * + * @throws ClassNotFoundException if the class can't be found. */ - JavaClass findClass(String className); + JavaClass loadClass(Class clazz) throws ClassNotFoundException; /** * Finds the class with the name provided, if the class isn't there, make an attempt to load it. + * + * @throws ClassNotFoundException if the class can't be found. */ - JavaClass loadClass(String className) throws java.lang.ClassNotFoundException; + JavaClass loadClass(String className) throws ClassNotFoundException; /** - * Finds the JavaClass instance for the given run-time class object + * Removes class from repository */ - JavaClass loadClass(Class clazz) throws java.lang.ClassNotFoundException; + void removeClass(JavaClass clazz); /** - * Clears all entries from cache. + * Stores the provided class under "clazz.getClassName()" */ - void clear(); + void storeClass(JavaClass clazz); } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/SyntheticRepository.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,22 +24,23 @@ import com.sun.org.apache.bcel.internal.classfile.ClassParser; import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.classfile.Utility; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; /** - * This repository is used in situations where a Class is created outside the - * realm of a ClassLoader. Classes are loaded from the file systems using the - * paths specified in the given class path. By default, this is the value - * returned by ClassPath.getClassPath().
    - * This repository uses a factory design, allowing it to maintain a collection - * of different classpaths, and as such It is designed to be used as a singleton - * per classpath. + * This repository is used in situations where a Class is created outside the realm of a ClassLoader. Classes are loaded + * from the file systems using the paths specified in the given class path. By default, this is the value returned by + * ClassPath.getClassPath(). + *

    + * This repository uses a factory design, allowing it to maintain a collection of different classpaths, and as such It + * is designed to be used as a singleton per classpath. + *

    * * @see com.sun.org.apache.bcel.internal.Repository * - * @LastModified: May 2021 + * @LastModified: Feb 2023 */ public class SyntheticRepository implements Repository { @@ -54,20 +55,11 @@ } /** - * Store a new JavaClass instance into this Repository. - */ - @Override - public void storeClass(final JavaClass clazz) { - loadedClasses.put(clazz.getClassName(), new SoftReference<>(clazz)); - clazz.setRepository(this); - } - - /** - * Remove class from repository + * Clear all entries from cache. */ @Override - public void removeClass(final JavaClass clazz) { - loadedClasses.remove(clazz.getClassName()); + public void clear() { + loadedClasses.clear(); } /** @@ -76,48 +68,36 @@ @Override public JavaClass findClass(final String className) { final SoftReference ref = loadedClasses.get(className); - if (ref == null) { - return null; -} - return ref.get(); + return ref == null ? null : ref.get(); } /** - * Finds a JavaClass object by name. If it is already in this Repository, the - * Repository version is returned. - * - * @param className the name of the class - * @return the JavaClass object - * @throws ClassNotFoundException if the class is not in the Repository + * Remove class from repository */ @Override - public JavaClass loadClass(String className) throws ClassNotFoundException { - if ((className == null) || className.isEmpty()) { - throw new IllegalArgumentException("Invalid class name " + className); + public void removeClass(final JavaClass clazz) { + loadedClasses.remove(clazz.getClassName()); } - className = className.replace('/', '.'); // Just in case, canonical form - final JavaClass clazz = findClass(className); - if (clazz != null) { - return clazz; - } - IOException e = new IOException("Couldn't find: " + className + ".class"); - throw new ClassNotFoundException("Exception while looking for class " + - className + ": " + e, e); + /** + * Store a new JavaClass instance into this Repository. + */ + @Override + public void storeClass(final JavaClass clazz) { + // Not calling super.storeClass because this subclass maintains the mapping. + loadedClasses.put(clazz.getClassName(), new SoftReference<>(clazz)); + clazz.setRepository(this); } /** - * Find the JavaClass object for a runtime Class object. If a class with the - * same name is already in this Repository, the Repository version is - * returned. Otherwise, getResourceAsStream() is called on the Class object - * to find the class's representation. If the representation is found, it is - * added to the Repository. + * Finds the JavaClass object for a runtime Class object. If a class with the same name is already in this Repository, + * the Repository version is returned. Otherwise, getResourceAsStream() is called on the Class object to find the + * class's representation. If the representation is found, it is added to the Repository. * * @see Class * @param clazz the runtime Class object * @return JavaClass object for given runtime class - * @throws ClassNotFoundException if the class is not in the Repository, and - * its representation could not be found + * @throws ClassNotFoundException if the class is not in the Repository, and its representation could not be found */ @Override public JavaClass loadClass(final Class clazz) throws ClassNotFoundException { @@ -125,52 +105,54 @@ final JavaClass repositoryClass = findClass(className); if (repositoryClass != null) { return repositoryClass; - } + } String name = className; final int i = name.lastIndexOf('.'); if (i > 0) { name = name.substring(i + 1); } - JavaClass cls = null; - try (InputStream clsStream = clazz.getResourceAsStream(name + ".class")) { - return cls = loadClass(clsStream, className); + + try (InputStream clsStream = clazz.getResourceAsStream(name + JavaClass.EXTENSION)) { + return loadClass(clsStream, className); } catch (final IOException e) { - return cls; + return null; } - } - - private JavaClass loadClass(final InputStream is, final String className) - throws ClassNotFoundException { + private JavaClass loadClass(final InputStream inputStream, final String className) throws ClassNotFoundException { try { - if (is != null) { - final ClassParser parser = new ClassParser(is, className); + if (inputStream != null) { + final ClassParser parser = new ClassParser(inputStream, className); final JavaClass clazz = parser.parse(); storeClass(clazz); return clazz; } } catch (final IOException e) { - throw new ClassNotFoundException("Exception while looking for class " - + className + ": " + e, e); - } finally { - if (is != null) { - try { - is.close(); - } catch (final IOException e) { - // ignored - } - } + throw new ClassNotFoundException("Exception while looking for class " + className + ": " + e, e); } - throw new ClassNotFoundException("SyntheticRepository could not load " - + className); + throw new ClassNotFoundException("ClassRepository could not load " + className); } /** - * Clear all entries from cache. + * Finds a JavaClass object by name. If it is already in this Repository, the Repository version is returned. Otherwise, + * the Repository's classpath is searched for the class (and it is added to the Repository if found). + * + * @param className the name of the class + * @return the JavaClass object + * @throws ClassNotFoundException if the class is not in the Repository, and could not be found on the classpath */ @Override - public void clear() { - loadedClasses.clear(); + public JavaClass loadClass(String className) throws ClassNotFoundException { + if (className == null || className.isEmpty()) { + throw new IllegalArgumentException("Invalid class name " + className); + } + className = Utility.pathToPackage(className); // Just in case, canonical form + final JavaClass clazz = findClass(className); + if (clazz != null) { + return clazz; + } + IOException e = new IOException("Couldn't find: " + className + ".class"); + throw new ClassNotFoundException("Exception while looking for class " + + className + ": " + e, e); } } diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -1420,32 +1420,23 @@ } } } - - // The next is kind of a hack to keep from escaping in the case - // of Shift_JIS and the like. - - /* - else if ((ch < m_maxCharacter) && (m_maxCharacter == 0xFFFF) - && (ch != 160)) - { - writer.write(ch); // no escaping in this case - } - else - */ - String outputStringForChar = m_charInfo.getOutputStringForChar(ch); - if (null != outputStringForChar) - { - writer.write(outputStringForChar); - } - else if (escapingNotNeeded(ch)) - { - writer.write(ch); // no escaping in this case - } else { - writer.write("&#"); - writer.write(Integer.toString(ch)); - writer.write(';'); + String outputStringForChar = m_charInfo.getOutputStringForChar(ch); + if (null != outputStringForChar) + { + writer.write(outputStringForChar); + } + else if (escapingNotNeeded(ch)) + { + writer.write(ch); // no escaping in this case + } + else + { + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + } } } cleanStart = i + 1; diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/jdk/xml/internal/Utils.java openjdk-lts-11.0.21+9/src/java.xml/share/classes/jdk/xml/internal/Utils.java --- openjdk-lts-11.0.20.1+1/src/java.xml/share/classes/jdk/xml/internal/Utils.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/classes/jdk/xml/internal/Utils.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * 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. 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.xml.internal; + +import java.util.Arrays; + +/** + * General utility. Use JdkXmlUtils for XML processing related functions. + */ +public class Utils { + /** + * Creates a new array with copies of the original array and additional items + * appended to the end of it. + * + * @param original the original array + * @param items items to be appended to the original array + * @return a new array with copies of the original array and additional items + */ + public static Class[] arraysAppend(final Class[] original, final Class... items) { + if (original == null && items == null) { + return null; + } + if (items == null) { + return Arrays.copyOf(original, original.length); + } + if (original == null) { + return Arrays.copyOf(items, items.length); + } + + Class[] result = Arrays.copyOf(original, original.length + items.length); + System.arraycopy(items, 0, result, original.length, items.length); + return result; + } +} diff -Nru openjdk-lts-11.0.20.1+1/src/java.xml/share/legal/bcel.md openjdk-lts-11.0.21+9/src/java.xml/share/legal/bcel.md --- openjdk-lts-11.0.20.1+1/src/java.xml/share/legal/bcel.md 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/java.xml/share/legal/bcel.md 2023-10-06 05:33:33.000000000 +0000 @@ -1,10 +1,10 @@ -## Apache Commons Byte Code Engineering Library (BCEL) Version 6.5.0 +## Apache Commons Byte Code Engineering Library (BCEL) Version 6.7.0 ### Apache Commons BCEL Notice
     
         Apache Commons BCEL
    -    Copyright 2004-2020 The Apache Software Foundation
    +    Copyright 2004-2022 The Apache Software Foundation
     
         This product includes software developed at
         The Apache Software Foundation (https://www.apache.org/).
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties openjdk-lts-11.0.21+9/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties
    --- openjdk-lts-11.0.20.1+1/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	2023-10-06 05:33:33.000000000 +0000
    @@ -121,8 +121,6 @@
         
     javac.opt.arg.release=\
         
    -javac.opt.arg.release=\
    -    
     javac.opt.arg.number=\
         
     javac.opt.plugin=\
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java	2023-10-06 05:33:33.000000000 +0000
    @@ -90,6 +90,9 @@
         // flags indicating whether the key is a token object, sensitive, extractable
         final boolean tokenObject, sensitive, extractable;
     
    +    // flag indicating whether the current token is NSS
    +    final transient boolean isNSS;
    +
         private final NativeKeyHolder keyIDHolder;
     
         private static final boolean DISABLE_NATIVE_KEYS_EXTRACTION;
    @@ -136,7 +139,7 @@
             this.sensitive = sensitive;
             this.extractable = extractable;
             char[] tokenLabel = this.token.tokenInfo.label;
    -        boolean isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S'
    +        isNSS = (tokenLabel[0] == 'N' && tokenLabel[1] == 'S'
                     && tokenLabel[2] == 'S');
             boolean extractKeyInfo = (!DISABLE_NATIVE_KEYS_EXTRACTION && isNSS &&
                     extractable && !tokenObject);
    @@ -237,7 +240,8 @@
             } else {
                 // XXX short term serialization for unextractable keys
                 throw new NotSerializableException
    -                ("Cannot serialize sensitive and unextractable keys");
    +                    ("Cannot serialize sensitive, unextractable " + (isNSS ?
    +                    ", and NSS token keys" : "keys"));
             }
             return new KeyRep(type, getAlgorithm(), format, getEncoded());
         }
    @@ -460,7 +464,7 @@
             }
             public String getFormat() {
                 token.ensureValid();
    -            if (sensitive || (extractable == false)) {
    +            if (sensitive || !extractable || (isNSS && tokenObject)) {
                     return null;
                 } else {
                     return "RAW";
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2003, 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
    @@ -32,6 +32,8 @@
     import java.security.spec.*;
     
     import sun.security.rsa.RSAPublicKeyImpl;
    +import sun.security.rsa.RSAPrivateCrtKeyImpl;
    +import sun.security.rsa.RSAUtil.KeyType;
     import static sun.security.pkcs11.TemplateManager.*;
     import sun.security.pkcs11.wrapper.*;
     import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
    @@ -58,14 +60,11 @@
                         rsaKey.getModulus(),
                         rsaKey.getPublicExponent()
                     );
    -            } else if ("X.509".equals(key.getFormat())) {
    +            } else {
                     // let SunRsaSign provider parse for us, then recurse
    -                byte[] encoded = key.getEncoded();
    -                key = RSAPublicKeyImpl.newKey(encoded);
    +                key = RSAPublicKeyImpl.newKey(KeyType.RSA, key.getFormat(),
    +                        key.getEncoded());
                     return implTranslatePublicKey(key);
    -            } else {
    -                throw new InvalidKeyException("PublicKey must be instance "
    -                        + "of RSAPublicKey or have X.509 encoding");
                 }
             } catch (PKCS11Exception e) {
                 throw new InvalidKeyException("Could not create RSA public key", e);
    @@ -93,14 +92,11 @@
                         rsaKey.getModulus(),
                         rsaKey.getPrivateExponent()
                     );
    -            } else if ("PKCS#8".equals(key.getFormat())) {
    +            } else {
                     // let SunRsaSign provider parse for us, then recurse
    -                byte[] encoded = key.getEncoded();
    -                key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
    +                key = RSAPrivateCrtKeyImpl.newKey(KeyType.RSA, key.getFormat(),
    +                        key.getEncoded());
                     return implTranslatePrivateKey(key);
    -            } else {
    -                throw new InvalidKeyException("Private key must be instance "
    -                        + "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
                 }
             } catch (PKCS11Exception e) {
                 throw new InvalidKeyException("Could not create RSA private key", e);
    @@ -113,8 +109,8 @@
             token.ensureValid();
             if (keySpec instanceof X509EncodedKeySpec) {
                 try {
    -                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
    -                PublicKey key = RSAPublicKeyImpl.newKey(encoded);
    +                PublicKey key = RSAPublicKeyImpl.newKey(KeyType.RSA, "X.509",
    +                        ((X509EncodedKeySpec)keySpec).getEncoded());
                     return implTranslatePublicKey(key);
                 } catch (InvalidKeyException e) {
                     throw new InvalidKeySpecException
    @@ -143,9 +139,8 @@
             token.ensureValid();
             if (keySpec instanceof PKCS8EncodedKeySpec) {
                 try {
    -                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
    -                PrivateKey key =
    -                        sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
    +                PrivateKey key = RSAPrivateCrtKeyImpl.newKey(KeyType.RSA,
    +                        "PKCS#8", ((PKCS8EncodedKeySpec)keySpec).getEncoded());
                     return implTranslatePrivateKey(key);
                 } catch (GeneralSecurityException e) {
                     throw new InvalidKeySpecException
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java	2023-10-06 05:33:33.000000000 +0000
    @@ -46,6 +46,7 @@
     import sun.security.util.Debug;
     import sun.security.util.ResourcesMgr;
     import static sun.security.util.SecurityConstants.PROVIDER_VER;
    +import static sun.security.util.SecurityProviderConstants.getAliases;
     
     import sun.security.pkcs11.Secmod.*;
     
    @@ -408,19 +409,15 @@
             return System.identityHashCode(this);
         }
     
    -    private static String[] s(String ...aliases) {
    -        return aliases;
    -    }
    -
         private static final class Descriptor {
             final String type;
             final String algorithm;
             final String className;
    -        final String[] aliases;
    +        final List aliases;
             final int[] mechanisms;
     
             private Descriptor(String type, String algorithm, String className,
    -                String[] aliases, int[] mechanisms) {
    +                List aliases, int[] mechanisms) {
                 this.type = type;
                 this.algorithm = algorithm;
                 this.className = className;
    @@ -463,10 +460,16 @@
         }
     
         private static void d(String type, String algorithm, String className,
    -            String[] aliases, int[] m) {
    +            List aliases, int[] m) {
             register(new Descriptor(type, algorithm, className, aliases, m));
         }
     
    +    private static void dA(String type, String algorithm, String className,
    +            int[] m) {
    +        register(new Descriptor(type, algorithm, className,
    +                getAliases(algorithm), m));
    +    }
    +
         private static void register(Descriptor d) {
             for (int i = 0; i < d.mechanisms.length; i++) {
                 int m = d.mechanisms[i];
    @@ -528,51 +531,37 @@
                     m(CKM_MD2));
             d(MD, "MD5",            P11Digest,
                     m(CKM_MD5));
    -        d(MD, "SHA1",           P11Digest,
    -                s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
    +        dA(MD, "SHA-1",           P11Digest,
                     m(CKM_SHA_1));
     
    -        d(MD, "SHA-224",        P11Digest,
    -                s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"),
    +        dA(MD, "SHA-224",        P11Digest,
                     m(CKM_SHA224));
    -        d(MD, "SHA-256",        P11Digest,
    -                s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"),
    +        dA(MD, "SHA-256",        P11Digest,
                     m(CKM_SHA256));
    -        d(MD, "SHA-384",        P11Digest,
    -                s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"),
    +        dA(MD, "SHA-384",        P11Digest,
                     m(CKM_SHA384));
    -        d(MD, "SHA-512",        P11Digest,
    -                s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"),
    +        dA(MD, "SHA-512",        P11Digest,
                     m(CKM_SHA512));
    -        d(MD, "SHA-512/224",        P11Digest,
    -                s("2.16.840.1.101.3.4.2.5", "OID.2.16.840.1.101.3.4.2.5"),
    +        dA(MD, "SHA-512/224",        P11Digest,
                     m(CKM_SHA512_224));
    -        d(MD, "SHA-512/256",        P11Digest,
    -                s("2.16.840.1.101.3.4.2.6", "OID.2.16.840.1.101.3.4.2.6"),
    +        dA(MD, "SHA-512/256",        P11Digest,
                     m(CKM_SHA512_256));
     
             d(MAC, "HmacMD5",       P11MAC,
                     m(CKM_MD5_HMAC));
    -        d(MAC, "HmacSHA1",      P11MAC,
    -                s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
    +        dA(MAC, "HmacSHA1",      P11MAC,
                     m(CKM_SHA_1_HMAC));
    -        d(MAC, "HmacSHA224",    P11MAC,
    -                s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
    +        dA(MAC, "HmacSHA224",    P11MAC,
                     m(CKM_SHA224_HMAC));
    -        d(MAC, "HmacSHA256",    P11MAC,
    -                s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"),
    +        dA(MAC, "HmacSHA256",    P11MAC,
                     m(CKM_SHA256_HMAC));
    -        d(MAC, "HmacSHA384",    P11MAC,
    -                s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"),
    +        dA(MAC, "HmacSHA384",    P11MAC,
                     m(CKM_SHA384_HMAC));
    -        d(MAC, "HmacSHA512",    P11MAC,
    -                s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"),
    +        dA(MAC, "HmacSHA512",    P11MAC,
                     m(CKM_SHA512_HMAC));
    -        d(MAC, "HmacSHA512/224",    P11MAC,
    -                s("1.2.840.113549.2.12", "OID.1.2.840.113549.2.12"),
    +        dA(MAC, "HmacSHA512/224",    P11MAC,
                     m(CKM_SHA512_224_HMAC));
    -        d(MAC, "HmacSHA512/256",    P11MAC,
    -                s("1.2.840.113549.2.13", "OID.1.2.840.113549.2.13"),
    +        dA(MAC, "HmacSHA512/256",    P11MAC,
                     m(CKM_SHA512_256_HMAC));
     
             d(MAC, "SslMacMD5",     P11MAC,
    @@ -581,18 +570,20 @@
                     m(CKM_SSL3_SHA1_MAC));
     
             d(KPG, "RSA",           P11KeyPairGenerator,
    -                s("1.2.840.113549.1.1", "OID.1.2.840.113549.1.1"),
    +                getAliases("PKCS1"),
                     m(CKM_RSA_PKCS_KEY_PAIR_GEN));
     
    -        d(KPG, "DSA",           P11KeyPairGenerator,
    -                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
    +        List dhAlias = List.of("DiffieHellman");
    +
    +        dA(KPG, "DSA",           P11KeyPairGenerator,
                     m(CKM_DSA_KEY_PAIR_GEN));
    -        d(KPG, "DH",            P11KeyPairGenerator,    s("DiffieHellman"),
    +        d(KPG, "DH",            P11KeyPairGenerator,
    +                dhAlias,
                     m(CKM_DH_PKCS_KEY_PAIR_GEN));
             d(KPG, "EC",            P11KeyPairGenerator,
                     m(CKM_EC_KEY_PAIR_GEN));
     
    -        d(KG,  "ARCFOUR",       P11KeyGenerator,        s("RC4"),
    +        dA(KG,  "ARCFOUR",       P11KeyGenerator,
                     m(CKM_RC4_KEY_GEN));
             d(KG,  "DES",           P11KeyGenerator,
                     m(CKM_DES_KEY_GEN));
    @@ -608,12 +599,12 @@
             // register (Secret)KeyFactories if there are any mechanisms
             // for a particular algorithm that we support
             d(KF, "RSA",            P11RSAKeyFactory,
    -                s("1.2.840.113549.1.1", "OID.1.2.840.113549.1.1"),
    +                getAliases("PKCS1"),
                     m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(KF, "DSA",            P11DSAKeyFactory,
    -                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
    +        dA(KF, "DSA",            P11DSAKeyFactory,
                     m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
    -        d(KF, "DH",             P11DHKeyFactory,        s("DiffieHellman"),
    +        d(KF, "DH",             P11DHKeyFactory,
    +                dhAlias,
                     m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
             d(KF, "EC",             P11DHKeyFactory,
                     m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
    @@ -621,8 +612,7 @@
     
             // AlgorithmParameters for EC.
             // Only needed until we have an EC implementation in the SUN provider.
    -        d(AGP, "EC",            "sun.security.util.ECParameters",
    -                s("1.2.840.10045.2.1"),
    +        dA(AGP, "EC",            "sun.security.util.ECParameters",
                     m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
                         CKM_ECDSA, CKM_ECDSA_SHA1));
     
    @@ -630,24 +620,23 @@
             d(AGP, "GCM",            "sun.security.util.GCMParameters",
                     m(CKM_AES_GCM));
     
    -        d(AGP, "ChaCha20-Poly1305",
    +        dA(AGP, "ChaCha20-Poly1305",
                     "com.sun.crypto.provider.ChaCha20Poly1305Parameters",
    -                s("1.2.840.113549.1.9.16.3.18", "OID.1.2.840.113549.1.9.16.3.18"),
                     m(CKM_CHACHA20_POLY1305));
     
    -        d(KA, "DH",             P11KeyAgreement,        s("DiffieHellman"),
    +        d(KA, "DH",             P11KeyAgreement,
    +                dhAlias,
                     m(CKM_DH_PKCS_DERIVE));
             d(KA, "ECDH",           "sun.security.pkcs11.P11ECDHKeyAgreement",
                     m(CKM_ECDH1_DERIVE));
     
    -        d(SKF, "ARCFOUR",       P11SecretKeyFactory,    s("RC4"),
    +        dA(SKF, "ARCFOUR",      P11SecretKeyFactory,
                     m(CKM_RC4));
             d(SKF, "DES",           P11SecretKeyFactory,
                     m(CKM_DES_CBC));
             d(SKF, "DESede",        P11SecretKeyFactory,
                     m(CKM_DES3_CBC));
    -        d(SKF, "AES",           P11SecretKeyFactory,
    -                s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
    +        dA(SKF, "AES",          P11SecretKeyFactory,
                     m(CKM_AES_CBC));
             d(SKF, "Blowfish",      P11SecretKeyFactory,
                     m(CKM_BLOWFISH_CBC));
    @@ -655,7 +644,7 @@
                     m(CKM_CHACHA20_POLY1305));
     
             // XXX attributes for Ciphers (supported modes, padding)
    -        d(CIP, "ARCFOUR",                       P11Cipher,      s("RC4"),
    +        dA(CIP, "ARCFOUR",                      P11Cipher,
                     m(CKM_RC4));
             d(CIP, "DES/CBC/NoPadding",             P11Cipher,
                     m(CKM_DES_CBC));
    @@ -663,7 +652,8 @@
                     m(CKM_DES_CBC_PAD, CKM_DES_CBC));
             d(CIP, "DES/ECB/NoPadding",             P11Cipher,
                     m(CKM_DES_ECB));
    -        d(CIP, "DES/ECB/PKCS5Padding",          P11Cipher,      s("DES"),
    +        d(CIP, "DES/ECB/PKCS5Padding",          P11Cipher,
    +                List.of("DES"),
                     m(CKM_DES_ECB));
     
             d(CIP, "DESede/CBC/NoPadding",          P11Cipher,
    @@ -672,47 +662,40 @@
                     m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
             d(CIP, "DESede/ECB/NoPadding",          P11Cipher,
                     m(CKM_DES3_ECB));
    -        d(CIP, "DESede/ECB/PKCS5Padding",       P11Cipher,      s("DESede"),
    +        d(CIP, "DESede/ECB/PKCS5Padding",       P11Cipher,
    +                List.of("DESede"),
                     m(CKM_DES3_ECB));
             d(CIP, "AES/CBC/NoPadding",             P11Cipher,
                     m(CKM_AES_CBC));
    -        d(CIP, "AES_128/CBC/NoPadding",          P11Cipher,
    -                s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
    +        dA(CIP, "AES_128/CBC/NoPadding",        P11Cipher,
                     m(CKM_AES_CBC));
    -        d(CIP, "AES_192/CBC/NoPadding",          P11Cipher,
    -                s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
    +        dA(CIP, "AES_192/CBC/NoPadding",        P11Cipher,
                     m(CKM_AES_CBC));
    -        d(CIP, "AES_256/CBC/NoPadding",          P11Cipher,
    -                s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
    +        dA(CIP, "AES_256/CBC/NoPadding",        P11Cipher,
                     m(CKM_AES_CBC));
             d(CIP, "AES/CBC/PKCS5Padding",          P11Cipher,
                     m(CKM_AES_CBC_PAD, CKM_AES_CBC));
             d(CIP, "AES/ECB/NoPadding",             P11Cipher,
                     m(CKM_AES_ECB));
    -        d(CIP, "AES_128/ECB/NoPadding",          P11Cipher,
    -                s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
    +        dA(CIP, "AES_128/ECB/NoPadding",        P11Cipher,
                     m(CKM_AES_ECB));
    -        d(CIP, "AES_192/ECB/NoPadding",          P11Cipher,
    -                s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
    +        dA(CIP, "AES_192/ECB/NoPadding",        P11Cipher,
                     m(CKM_AES_ECB));
    -        d(CIP, "AES_256/ECB/NoPadding",          P11Cipher,
    -                s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
    +        dA(CIP, "AES_256/ECB/NoPadding",        P11Cipher,
                     m(CKM_AES_ECB));
    -        d(CIP, "AES/ECB/PKCS5Padding",          P11Cipher,      s("AES"),
    +        d(CIP, "AES/ECB/PKCS5Padding",          P11Cipher,
    +                List.of("AES"),
                     m(CKM_AES_ECB));
             d(CIP, "AES/CTR/NoPadding",             P11Cipher,
                     m(CKM_AES_CTR));
     
             d(CIP, "AES/GCM/NoPadding",             P11AEADCipher,
                     m(CKM_AES_GCM));
    -        d(CIP, "AES_128/GCM/NoPadding",          P11AEADCipher,
    -                s("2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"),
    +        dA(CIP, "AES_128/GCM/NoPadding",        P11AEADCipher,
                     m(CKM_AES_GCM));
    -        d(CIP, "AES_192/GCM/NoPadding",          P11AEADCipher,
    -                s("2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"),
    +        dA(CIP, "AES_192/GCM/NoPadding",        P11AEADCipher,
                     m(CKM_AES_GCM));
    -        d(CIP, "AES_256/GCM/NoPadding",          P11AEADCipher,
    -                s("2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46"),
    +        dA(CIP, "AES_256/GCM/NoPadding",        P11AEADCipher,
                     m(CKM_AES_GCM));
     
             d(CIP, "Blowfish/CBC/NoPadding",        P11Cipher,
    @@ -720,56 +703,46 @@
             d(CIP, "Blowfish/CBC/PKCS5Padding",     P11Cipher,
                     m(CKM_BLOWFISH_CBC));
     
    -        d(CIP, "ChaCha20-Poly1305",             P11AEADCipher,
    -                s("1.2.840.113549.1.9.16.3.18", "OID.1.2.840.113549.1.9.16.3.18"),
    +        dA(CIP, "ChaCha20-Poly1305",            P11AEADCipher,
                     m(CKM_CHACHA20_POLY1305));
     
    -        d(CIP, "RSA/ECB/PKCS1Padding",          P11RSACipher,   s("RSA"),
    +        d(CIP, "RSA/ECB/PKCS1Padding",          P11RSACipher,
    +                List.of("RSA"),
                     m(CKM_RSA_PKCS));
             d(CIP, "RSA/ECB/NoPadding",             P11RSACipher,
                     m(CKM_RSA_X_509));
     
    -        d(SIG, "RawDSA",        P11Signature,   s("NONEwithDSA"),
    +        d(SIG, "RawDSA",        P11Signature,
    +                List.of("NONEwithDSA"),
                     m(CKM_DSA));
    -        d(SIG, "DSA",           P11Signature,
    -                s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
    -                  "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
    +        dA(SIG, "SHA1withDSA",           P11Signature,
                     m(CKM_DSA_SHA1, CKM_DSA));
    -        d(SIG, "SHA224withDSA", P11Signature,
    -                s("2.16.840.1.101.3.4.3.1", "OID.2.16.840.1.101.3.4.3.1"),
    +        dA(SIG, "SHA224withDSA", P11Signature,
                     m(CKM_DSA_SHA224));
    -        d(SIG, "SHA256withDSA", P11Signature,
    -                s("2.16.840.1.101.3.4.3.2", "OID.2.16.840.1.101.3.4.3.2"),
    +        dA(SIG, "SHA256withDSA", P11Signature,
                     m(CKM_DSA_SHA256));
    -        d(SIG, "SHA384withDSA", P11Signature,
    -                s("2.16.840.1.101.3.4.3.3", "OID.2.16.840.1.101.3.4.3.3"),
    +        dA(SIG, "SHA384withDSA", P11Signature,
                     m(CKM_DSA_SHA384));
    -        d(SIG, "SHA512withDSA", P11Signature,
    -                s("2.16.840.1.101.3.4.3.4", "OID.2.16.840.1.101.3.4.3.4"),
    +        dA(SIG, "SHA512withDSA", P11Signature,
                     m(CKM_DSA_SHA512));
             d(SIG, "RawDSAinP1363Format",   P11Signature,
    -                s("NONEwithDSAinP1363Format"),
    +                List.of("NONEwithDSAinP1363Format"),
                     m(CKM_DSA));
             d(SIG, "DSAinP1363Format",      P11Signature,
    -                s("SHA1withDSAinP1363Format"),
    +                List.of("SHA1withDSAinP1363Format"),
                     m(CKM_DSA_SHA1, CKM_DSA));
     
             d(SIG, "NONEwithECDSA", P11Signature,
                     m(CKM_ECDSA));
    -        d(SIG, "SHA1withECDSA", P11Signature,
    -                s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
    +        dA(SIG, "SHA1withECDSA", P11Signature,
                     m(CKM_ECDSA_SHA1, CKM_ECDSA));
    -        d(SIG, "SHA224withECDSA",       P11Signature,
    -                s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
    +        dA(SIG, "SHA224withECDSA",       P11Signature,
                     m(CKM_ECDSA));
    -        d(SIG, "SHA256withECDSA",       P11Signature,
    -                s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"),
    +        dA(SIG, "SHA256withECDSA",       P11Signature,
                     m(CKM_ECDSA));
    -        d(SIG, "SHA384withECDSA",       P11Signature,
    -                s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"),
    +        dA(SIG, "SHA384withECDSA",       P11Signature,
                     m(CKM_ECDSA));
    -        d(SIG, "SHA512withECDSA",       P11Signature,
    -                s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
    +        dA(SIG, "SHA512withECDSA",       P11Signature,
                     m(CKM_ECDSA));
             d(SIG, "NONEwithECDSAinP1363Format",   P11Signature,
                     m(CKM_ECDSA));
    @@ -783,30 +756,21 @@
                     m(CKM_ECDSA));
             d(SIG, "SHA512withECDSAinP1363Format", P11Signature,
                     m(CKM_ECDSA));
    -        d(SIG, "MD2withRSA",    P11Signature,
    -                s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
    +        dA(SIG, "MD2withRSA",    P11Signature,
                     m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "MD5withRSA",    P11Signature,
    -                s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
    +        dA(SIG, "MD5withRSA",    P11Signature,
                     m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "SHA1withRSA",   P11Signature,
    -                s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
    -                  "1.3.14.3.2.29"),
    +        dA(SIG, "SHA1withRSA",   P11Signature,
                     m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "SHA224withRSA", P11Signature,
    -                s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
    +        dA(SIG, "SHA224withRSA", P11Signature,
                     m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "SHA256withRSA", P11Signature,
    -                s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"),
    +        dA(SIG, "SHA256withRSA", P11Signature,
                     m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "SHA384withRSA", P11Signature,
    -                s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"),
    +        dA(SIG, "SHA384withRSA", P11Signature,
                     m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "SHA512withRSA", P11Signature,
    -                s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"),
    +        dA(SIG, "SHA512withRSA", P11Signature,
                     m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
    -        d(SIG, "RSASSA-PSS", P11PSSSignature,
    -                s("1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10"),
    +        dA(SIG, "RSASSA-PSS", P11PSSSignature,
                     m(CKM_RSA_PKCS_PSS));
             d(SIG, "SHA1withRSASSA-PSS", P11PSSSignature,
                     m(CKM_SHA1_RSA_PKCS_PSS));
    @@ -821,7 +785,7 @@
     
             d(KG, "SunTlsRsaPremasterSecret",
                         "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
    -                    s("SunTls12RsaPremasterSecret"),
    +                List.of("SunTls12RsaPremasterSecret"),
                     m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
             d(KG, "SunTlsMasterSecret",
                         "sun.security.pkcs11.P11TlsMasterSecretGenerator",
    @@ -1128,7 +1092,7 @@
                     if (config.isEnabled(PCKM_KEYSTORE)) {
                         putService(new P11Service(token, KS, "PKCS11",
                             "sun.security.pkcs11.P11KeyStore",
    -                        s("PKCS11-" + config.getName()),
    +                        List.of("PKCS11-" + config.getName()),
                             PCKM_KEYSTORE));
                     }
                     return null;
    @@ -1148,17 +1112,13 @@
             private final long mechanism;
     
             P11Service(Token token, String type, String algorithm,
    -                String className, String[] al, long mechanism) {
    -            super(token.provider, type, algorithm, className, toList(al),
    +                String className, List al, long mechanism) {
    +            super(token.provider, type, algorithm, className, al,
                         type.equals(SR) ? Map.of("ThreadSafe", "true") : null);
                 this.token = token;
                 this.mechanism = mechanism & 0xFFFFFFFFL;
             }
     
    -        private static List toList(String[] aliases) {
    -            return (aliases == null) ? null : Arrays.asList(aliases);
    -        }
    -
             public Object newInstance(Object param)
                     throws NoSuchAlgorithmException {
                 if (token.isValid() == false) {
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2003, 2013, 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
    @@ -420,11 +420,26 @@
     
         private Object writeReplace() throws ObjectStreamException {
             if (isValid() == false) {
    -            throw new NotSerializableException("Token has been removed");
    +            throw new InvalidObjectException("Token has been removed");
             }
             return new TokenRep(this);
         }
     
    +    /**
    +     * Restores the state of this object from the stream.
    +     * 

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "Tokens are not directly deserializable"); + } + // serialized representation of a token // tokens can only be de-serialized within the same VM invocation // and if the token has not been removed in the meantime @@ -447,7 +462,7 @@ } } } - throw new NotSerializableException("Could not find token"); + throw new InvalidObjectException("Could not find token"); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPrivateKeyImpl.java openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPrivateKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPrivateKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPrivateKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,6 +26,8 @@ package sun.security.ec; import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.*; @@ -38,7 +40,7 @@ /** * Key implementation for EC private keys. - * + *

    * ASN.1 syntax for EC private keys from SEC 1 v1.5 (draft): * *

    @@ -208,4 +210,19 @@
                 throw new InvalidKeyException("Invalid EC private key", e);
             }
         }
    +
    +    /**
    +     * Restores the state of this object from the stream.
    +     * 

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "ECPrivateKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPublicKeyImpl.java openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPublicKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPublicKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/ECPublicKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. * 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 @@ import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.*; import java.security.interfaces.*; import java.security.spec.*; @@ -122,10 +124,25 @@ + "\n parameters: " + params; } - protected Object writeReplace() throws java.io.ObjectStreamException { + private Object writeReplace() throws java.io.ObjectStreamException { return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), getEncoded()); } + + /** + * Restores the state of this object from the stream. + *

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "ECPublicKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,11 +27,11 @@ import java.util.*; import java.security.*; -import java.util.regex.Pattern; import sun.security.util.CurveDB; import sun.security.util.NamedCurve; import static sun.security.util.SecurityConstants.PROVIDER_VER; +import static sun.security.util.SecurityProviderConstants.*; /** * Provider class for the Elliptic Curve provider. @@ -69,6 +69,13 @@ } } + private static class ProviderServiceA extends ProviderService { + ProviderServiceA(Provider p, String type, String algo, String cn, + HashMap attrs) { + super(p, type, algo, cn, getAliases(algo), attrs); + } + } + private static class ProviderService extends Provider.Service { ProviderService(Provider p, String type, String algo, String cn) { @@ -76,9 +83,8 @@ } ProviderService(Provider p, String type, String algo, String cn, - String[] aliases, HashMap attrs) { - super(p, type, algo, cn, - (aliases == null? null : Arrays.asList(aliases)), attrs); + List aliases, HashMap attrs) { + super(p, type, algo, cn, aliases, attrs); } @Override @@ -184,7 +190,7 @@ */ putService(new ProviderService(this, "KeyFactory", "EC", "sun.security.ec.ECKeyFactory", - new String[] { "EllipticCurve" }, ATTRS)); + List.of("EllipticCurve"), ATTRS)); /* * Algorithm Parameter engine @@ -192,7 +198,6 @@ // "AlgorithmParameters.EC SupportedCurves" prop used by unit test boolean firstCurve = true; StringBuilder names = new StringBuilder(); - Pattern nameSplitPattern = Pattern.compile(CurveDB.SPLIT_PATTERN); Collection supportedCurves = CurveDB.getSupportedCurves(); @@ -204,10 +209,9 @@ } names.append("["); - - String[] commonNames = nameSplitPattern.split(namedCurve.getName()); + String[] commonNames = namedCurve.getNameAndAliases(); for (String commonName : commonNames) { - names.append(commonName.trim()); + names.append(commonName); names.append(","); } @@ -218,10 +222,8 @@ HashMap apAttrs = new HashMap<>(ATTRS); apAttrs.put("SupportedCurves", names.toString()); - putService(new ProviderService(this, "AlgorithmParameters", - "EC", "sun.security.util.ECParameters", - new String[] { "EllipticCurve", "1.2.840.10045.2.1", "OID.1.2.840.10045.2.1" }, - apAttrs)); + putService(new ProviderServiceA(this, "AlgorithmParameters", + "EC", "sun.security.util.ECParameters", apAttrs)); putXDHEntries(); @@ -239,25 +241,20 @@ putService(new ProviderService(this, "Signature", "NONEwithECDSA", "sun.security.ec.ECDSASignature$Raw", null, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA1withECDSA", "sun.security.ec.ECDSASignature$SHA1", - new String[] { "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1" }, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA224withECDSA", "sun.security.ec.ECDSASignature$SHA224", - new String[] { "1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"}, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA256withECDSA", "sun.security.ec.ECDSASignature$SHA256", - new String[] { "1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"}, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA384withECDSA", "sun.security.ec.ECDSASignature$SHA384", - new String[] { "1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3" }, ATTRS)); - putService(new ProviderService(this, "Signature", + putService(new ProviderServiceA(this, "Signature", "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512", - new String[] { "1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4" }, ATTRS)); putService(new ProviderService(this, "Signature", @@ -284,7 +281,7 @@ */ putService(new ProviderService(this, "KeyPairGenerator", "EC", "sun.security.ec.ECKeyPairGenerator", - new String[] { "EllipticCurve" }, ATTRS)); + List.of("EllipticCurve"), ATTRS)); /* * Key Agreement engine @@ -301,30 +298,29 @@ /* XDH does not require native implementation */ putService(new ProviderService(this, "KeyFactory", "XDH", "sun.security.ec.XDHKeyFactory", null, ATTRS)); - putService(new ProviderService(this, "KeyFactory", + putService(new ProviderServiceA(this, "KeyFactory", "X25519", "sun.security.ec.XDHKeyFactory.X25519", - new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS)); - putService(new ProviderService(this, "KeyFactory", + ATTRS)); + putService(new ProviderServiceA(this, "KeyFactory", "X448", "sun.security.ec.XDHKeyFactory.X448", - new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); + ATTRS)); putService(new ProviderService(this, "KeyPairGenerator", "XDH", "sun.security.ec.XDHKeyPairGenerator", null, ATTRS)); - putService(new ProviderService(this, "KeyPairGenerator", + putService(new ProviderServiceA(this, "KeyPairGenerator", "X25519", "sun.security.ec.XDHKeyPairGenerator.X25519", - new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS)); - putService(new ProviderService(this, "KeyPairGenerator", + ATTRS)); + putService(new ProviderServiceA(this, "KeyPairGenerator", "X448", "sun.security.ec.XDHKeyPairGenerator.X448", - new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); + ATTRS)); putService(new ProviderService(this, "KeyAgreement", "XDH", "sun.security.ec.XDHKeyAgreement", null, ATTRS)); - putService(new ProviderService(this, "KeyAgreement", + putService(new ProviderServiceA(this, "KeyAgreement", "X25519", "sun.security.ec.XDHKeyAgreement.X25519", - new String[]{"1.3.101.110", "OID.1.3.101.110"}, ATTRS)); - putService(new ProviderService(this, "KeyAgreement", + ATTRS)); + putService(new ProviderServiceA(this, "KeyAgreement", "X448", "sun.security.ec.XDHKeyAgreement.X448", - new String[]{"1.3.101.111", "OID.1.3.101.111"}, ATTRS)); - + ATTRS)); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPrivateKeyImpl.java openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPrivateKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPrivateKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPrivateKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -25,6 +25,9 @@ package sun.security.ec; +import java.io.ObjectInputStream; +import java.io.IOException; +import java.io.InvalidObjectException; import java.security.interfaces.XECPrivateKey; import java.util.Optional; import java.security.InvalidKeyException; @@ -87,5 +90,19 @@ public Optional getScalar() { return Optional.of(getK()); } -} + /** + * Restores the state of this object from the stream. + *

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "XDHPrivateKeyImpl keys are not directly deserializable"); + } +} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHPublicKeyImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 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 @@ -25,6 +25,9 @@ package sun.security.ec; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyRep; @@ -107,7 +110,7 @@ return "XDH"; } - protected Object writeReplace() throws java.io.ObjectStreamException { + private Object writeReplace() throws java.io.ObjectStreamException { return new KeyRep(KeyRep.Type.PUBLIC, getAlgorithm(), getFormat(), @@ -130,5 +133,20 @@ j--; } } + + /** + * Restores the state of this object from the stream. + *

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "XDHPublicKeyImpl keys are not directly deserializable"); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ec/share/classes/sun/security/ec/XECParameters.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -120,8 +120,8 @@ // set up X25519 try { BigInteger p = TWO.pow(255).subtract(BigInteger.valueOf(19)); - addParameters(255, p, 121665, (byte) 0x09, 3, - new int[]{1, 3, 101, 110}, NamedParameterSpec.X25519.getName(), + addParameters(255, p, 121665, (byte)0x09, 3, + "1.3.101.110", NamedParameterSpec.X25519.getName(), bySize, byOid, byName); } catch (IOException ex) { @@ -132,8 +132,8 @@ try { BigInteger p = TWO.pow(448).subtract(TWO.pow(224)) .subtract(BigInteger.ONE); - addParameters(448, p, 39081, (byte) 0x05, 2, - new int[]{1, 3, 101, 111}, NamedParameterSpec.X448.getName(), + addParameters(448, p, 39081, (byte)0x05, 2, + "1.3.101.111", NamedParameterSpec.X448.getName(), bySize, byOid, byName); } catch (IOException ex) { @@ -146,12 +146,12 @@ } private static void addParameters(int bits, BigInteger p, int a24, - byte basePoint, int logCofactor, int[] oidBytes, String name, + byte basePoint, int logCofactor, String objectId, String name, Map bySize, Map byOid, Map byName) throws IOException { - ObjectIdentifier oid = new ObjectIdentifier(oidBytes); + ObjectIdentifier oid = ObjectIdentifier.of(objectId); XECParameters params = new XECParameters(bits, p, a24, basePoint, logCofactor, oid, name); bySize.put(bits, params); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java openjdk-lts-11.0.21+9/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, 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 @@ -25,6 +25,9 @@ package sun.security.mscapi; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.PrivateKey; /** @@ -74,6 +77,22 @@ // This class is not serializable private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { - throw new java.io.NotSerializableException(); + throw new java.io.InvalidObjectException( + "CPrivateKeys are not serializable"); + } + + /** + * Restores the state of this object from the stream. + *

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "CPrivateKeys are not deserializable"); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java openjdk-lts-11.0.21+9/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, 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 @@ -25,6 +25,9 @@ package sun.security.mscapi; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.KeyException; @@ -108,7 +111,7 @@ public String toString() { StringBuffer sb = new StringBuffer(); - sb.append(algorithm + "PublicKey [size=").append(keyLength) + sb.append(algorithm).append("PublicKey [size=").append(keyLength) .append("]\n ECPoint: ").append(getW()) .append("\n params: ").append(getParams()); return sb.toString(); @@ -127,7 +130,7 @@ public String toString() { StringBuffer sb = new StringBuffer(); - sb.append(algorithm + "PublicKey [size=").append(keyLength) + sb.append(algorithm).append("PublicKey [size=").append(keyLength) .append(" bits, type="); if (handles.hCryptKey != 0) { sb.append(getKeyType(handles.hCryptKey)) @@ -221,6 +224,21 @@ getEncoded()); } + /** + * Restores the state of this object from the stream. + *

    + * Deserialization of this object is not supported. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new InvalidObjectException( + "CPublicKeys are not deserializable"); + } + // Returns the CAPI or CNG representation of the key. native byte[] getPublicKeyBlob(long hCryptProv, long hCryptKey) throws KeyException; diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java openjdk-lts-11.0.21+9/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -32,9 +32,10 @@ import java.security.InvalidParameterException; import java.security.ProviderException; import java.util.HashMap; -import java.util.Arrays; +import java.util.List; import static sun.security.util.SecurityConstants.PROVIDER_VER; +import static sun.security.util.SecurityProviderConstants.getAliases; /** * A Cryptographic Service Provider for the Microsoft Crypto API. @@ -56,16 +57,21 @@ } }); } + private static class ProviderServiceA extends ProviderService { + ProviderServiceA(Provider p, String type, String algo, String cn, + HashMap attrs) { + super(p, type, algo, cn, getAliases(algo), attrs); + } + } - private static final class ProviderService extends Provider.Service { + private static class ProviderService extends Provider.Service { ProviderService(Provider p, String type, String algo, String cn) { super(p, type, algo, cn, null, null); } ProviderService(Provider p, String type, String algo, String cn, - String[] aliases, HashMap attrs) { - super(p, type, algo, cn, - (aliases == null? null : Arrays.asList(aliases)), attrs); + List aliases, HashMap attrs) { + super(p, type, algo, cn, aliases, attrs); } @Override @@ -188,48 +194,47 @@ putService(new ProviderService(p, "Signature", "SHA1withRSA", "sun.security.mscapi.CSignature$SHA1withRSA", null, attrs)); - putService(new ProviderService(p, "Signature", - "SHA256withRSA", "sun.security.mscapi.CSignature$SHA256withRSA", - new String[] { "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11" }, + putService(new ProviderServiceA(p, "Signature", + "SHA256withRSA", + "sun.security.mscapi.CSignature$SHA256withRSA", attrs)); - putService(new ProviderService(p, "Signature", - "SHA384withRSA", "sun.security.mscapi.CSignature$SHA384withRSA", - new String[] { "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12" }, + putService(new ProviderServiceA(p, "Signature", + "SHA384withRSA", + "sun.security.mscapi.CSignature$SHA384withRSA", attrs)); - putService(new ProviderService(p, "Signature", - "SHA512withRSA", "sun.security.mscapi.CSignature$SHA512withRSA", - new String[] { "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13" }, + putService(new ProviderServiceA(p, "Signature", + "SHA512withRSA", + "sun.security.mscapi.CSignature$SHA512withRSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS", attrs)); - putService(new ProviderService(p, "Signature", - "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS", - new String[] { "1.2.840.113549.1.1.10", "OID.1.2.840.113549.1.1.10" }, - attrs)); putService(new ProviderService(p, "Signature", "MD5withRSA", "sun.security.mscapi.CSignature$MD5withRSA", null, attrs)); putService(new ProviderService(p, "Signature", "MD2withRSA", "sun.security.mscapi.CSignature$MD2withRSA", null, attrs)); - putService(new ProviderService(p, "Signature", - "SHA1withECDSA", "sun.security.mscapi.CSignature$SHA1withECDSA", - new String[] { "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1" }, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA224withECDSA", "sun.security.mscapi.CSignature$SHA224withECDSA", - new String[] { "1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"}, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA256withECDSA", "sun.security.mscapi.CSignature$SHA256withECDSA", - new String[] { "1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"}, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA384withECDSA", "sun.security.mscapi.CSignature$SHA384withECDSA", - new String[] { "1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"}, - attrs)); - putService(new ProviderService(p, "Signature", - "SHA512withECDSA", "sun.security.mscapi.CSignature$SHA512withECDSA", - new String[] { "1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"}, - attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA1withECDSA", + "sun.security.mscapi.CSignature$SHA1withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA224withECDSA", + "sun.security.mscapi.CSignature$SHA224withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA256withECDSA", + "sun.security.mscapi.CSignature$SHA256withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA384withECDSA", + "sun.security.mscapi.CSignature$SHA384withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA512withECDSA", + "sun.security.mscapi.CSignature$SHA512withECDSA", + attrs)); /* * Key Pair Generator engines */ diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,6 +25,9 @@ package com.oracle.security.ucrypto; +import java.util.List; +import static sun.security.util.SecurityProviderConstants.getAliases; + /** * Enum for representing the ucrypto mechanisms. * @@ -36,25 +39,30 @@ { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigestMD$MD5") }), SHA_1(new ServiceDesc[] - { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigestMD$SHA1", - "SHA-1", "SHA1") + { sd("MessageDigest", "SHA-1", "com.oracle.security.ucrypto.NativeDigestMD$SHA1", + getAliases("SHA-1")) }), SHA_256(new ServiceDesc[] { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigestMD$SHA256", - "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1") + getAliases("SHA-256")) }), SHA_384(new ServiceDesc[] { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigestMD$SHA384", - "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2") + getAliases("SHA-384")) }), SHA_512(new ServiceDesc[] { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigestMD$SHA512", - "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3") + getAliases("SHA-512")) }); ServiceDesc[] serviceDescs; - private static ServiceDesc sd(String type, String algo, String cn, String... aliases) { + private static ServiceDesc sd(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, null); + } + + private static ServiceDesc sd(String type, String algo, String cn, + List aliases) { return new ServiceDesc(type, algo, cn, aliases); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/ServiceDesc.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -42,15 +42,11 @@ this(type, algo, cn, null); } - ServiceDesc(String type, String algo, String cn, String[] aliases) { + ServiceDesc(String type, String algo, String cn, List aliases) { this.type = type; this.algo = algo; this.cn = cn; - if (aliases != null) { - this.aliases = Arrays.asList(aliases); - } else { - this.aliases = null; - } + this.aliases = aliases; } String getType() { return type; diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,9 @@ package com.oracle.security.ucrypto; +import java.util.List; +import static sun.security.util.SecurityProviderConstants.getAliases; + /** * Enum for representing the ucrypto mechanisms. * @@ -36,23 +39,23 @@ CRYPTO_AES_ECB(new ServiceDesc[] { sd("Cipher", "AES/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), sd("Cipher", "AES/ECB/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesEcbPKCS5", - "AES"), - sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", - "2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"), - sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", - "2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"), - sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", - "2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41") + List.of("AES")), + sdA("Cipher", "AES_128/ECB/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), + sdA("Cipher", "AES_192/ECB/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), + sdA("Cipher", "AES_256/ECB/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding") }), CRYPTO_AES_CBC(new ServiceDesc[] { sd("Cipher", "AES/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), sd("Cipher", "AES/CBC/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCbcPKCS5"), - sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", - "2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"), - sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", - "2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"), - sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", - "2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42") + sdA("Cipher", "AES_128/CBC/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), + sdA("Cipher", "AES_192/CBC/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), + sdA("Cipher", "AES_256/CBC/NoPadding", + "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding") }), // CRYPTO_AES_CBC_PAD(null), // Support added since S11.1; however we still use CRYPTO_AES_CBC due to known bug CRYPTO_AES_CTR(new ServiceDesc[] @@ -60,12 +63,12 @@ // CRYPTO_AES_CCM(null), // Need Java API for CK_AES_CCM_PARAMS CRYPTO_AES_GCM(new ServiceDesc[] { sd("Cipher", "AES/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), - sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", - "2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"), - sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", - "2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"), - sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", - "2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46") + sdA("Cipher", "AES_128/GCM/NoPadding", + "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), + sdA("Cipher", "AES_192/GCM/NoPadding", + "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), + sdA("Cipher", "AES_256/GCM/NoPadding", + "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding") }), // CRYPTO_AES_GMAC(null), // No support from Solaris CRYPTO_AES_CFB128(new ServiceDesc[] @@ -75,76 +78,87 @@ CRYPTO_RSA_PKCS(new ServiceDesc[] { sd("Cipher", "RSA/ECB/PKCS1Padding", "com.oracle.security.ucrypto.NativeRSACipher$PKCS1Padding", - "RSA") + List.of("RSA")) }), CRYPTO_RSA_X_509(new ServiceDesc[] { sd("Cipher", "RSA/ECB/NoPadding", "com.oracle.security.ucrypto.NativeRSACipher$NoPadding") }), CRYPTO_MD5_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "MD5withRSA", "com.oracle.security.ucrypto.NativeRSASignature$MD5", - "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4") + { sdA("Signature", "MD5withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$MD5") }), CRYPTO_SHA1_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA1withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA1", - "1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5", - "1.3.14.3.2.29") + { sdA("Signature", "SHA1withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA1") }), CRYPTO_SHA256_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA256withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA256", - "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11") + { sdA("Signature", "SHA256withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA256") }), CRYPTO_SHA384_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA384withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA384", - "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12") + { sdA("Signature", "SHA384withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA384") }), CRYPTO_SHA512_RSA_PKCS(new ServiceDesc[] - { sd("Signature", "SHA512withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA512", - "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13") + { sdA("Signature", "SHA512withRSA", + "com.oracle.security.ucrypto.NativeRSASignature$SHA512") }), CRYPTO_MD5(new ServiceDesc[] - { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigest$MD5") }), + { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigest$MD5") + }), CRYPTO_SHA1(new ServiceDesc[] - { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigest$SHA1", "SHA-1", "SHA1") }), + { sdA("MessageDigest", "SHA-1", + "com.oracle.security.ucrypto.NativeDigest$SHA1") + }), CRYPTO_SHA224(new ServiceDesc[] - { sd("MessageDigest", "SHA-224", "com.oracle.security.ucrypto.NativeDigest$SHA224", - "2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4") - }), + { sdA("MessageDigest", "SHA-224", + "com.oracle.security.ucrypto.NativeDigest$SHA224") + }), CRYPTO_SHA256(new ServiceDesc[] - { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigest$SHA256", - "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1") - }), + { sdA("MessageDigest", "SHA-256", + "com.oracle.security.ucrypto.NativeDigest$SHA256") + }), CRYPTO_SHA384(new ServiceDesc[] - { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigest$SHA384", - "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2") - }), + { sdA("MessageDigest", "SHA-384", + "com.oracle.security.ucrypto.NativeDigest$SHA384") + }), CRYPTO_SHA512(new ServiceDesc[] - { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigest$SHA512", - "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3") - }), + { sdA("MessageDigest", "SHA-512", + "com.oracle.security.ucrypto.NativeDigest$SHA512") + }), CRYPTO_SHA3_224(new ServiceDesc[] - { sd("MessageDigest", "SHA3-224", "com.oracle.security.ucrypto.NativeDigest$SHA3_224", - "2.16.840.1.101.3.4.2.7", "OID.2.16.840.1.101.3.4.2.7") - }), + { sdA("MessageDigest", "SHA3-224", + "com.oracle.security.ucrypto.NativeDigest$SHA3_224") + }), CRYPTO_SHA3_256(new ServiceDesc[] - { sd("MessageDigest", "SHA3-256", "com.oracle.security.ucrypto.NativeDigest$SHA3_256", - "2.16.840.1.101.3.4.2.8", "OID.2.16.840.1.101.3.4.2.8") - }), + { sdA("MessageDigest", "SHA3-256", + "com.oracle.security.ucrypto.NativeDigest$SHA3_256") + }), CRYPTO_SHA3_384(new ServiceDesc[] - { sd("MessageDigest", "SHA3-384", "com.oracle.security.ucrypto.NativeDigest$SHA3_384", - "2.16.840.1.101.3.4.2.9", "OID.2.16.840.1.101.3.4.2.9") - }), + { sdA("MessageDigest", "SHA3-384", + "com.oracle.security.ucrypto.NativeDigest$SHA3_384") + }), CRYPTO_SHA3_512(new ServiceDesc[] - { sd("MessageDigest", "SHA3-512", "com.oracle.security.ucrypto.NativeDigest$SHA3_512", - "2.16.840.1.101.3.4.2.10", "OID.2.16.840.1.101.3.4.2.10") - }); + { sdA("MessageDigest", "SHA3-512", + "com.oracle.security.ucrypto.NativeDigest$SHA3_512") + }); private int mech = 0; private final ServiceDesc[] serviceDescs; - private static ServiceDesc sd(String type, String algo, String cn, String... aliases) { + private static ServiceDesc sd(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, null); + } + + private static ServiceDesc sd(String type, String algo, String cn, + List aliases) { return new ServiceDesc(type, algo, cn, aliases); } + private static ServiceDesc sdA(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, getAliases(algo)); + } + UcryptoMech(ServiceDesc[] serviceDescs) { this.serviceDescs = serviceDescs; } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java --- openjdk-lts-11.0.20.1+1/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -32,7 +32,6 @@ import java.security.*; import static sun.security.util.SecurityConstants.PROVIDER_VER; - /** * OracleUcrypto provider main class. * @@ -134,9 +133,8 @@ } } - private static ServiceDesc sd(String type, String algo, String cn, - String... aliases) { - return new ServiceDesc(type, algo, cn, aliases); + private static ServiceDesc sd(String type, String algo, String cn) { + return new ServiceDesc(type, algo, cn, null); } private static final class ProviderService extends Provider.Service { diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java openjdk-lts-11.0.21+9/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java --- openjdk-lts-11.0.20.1+1/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java 2023-10-06 05:33:33.000000000 +0000 @@ -121,6 +121,9 @@ } public boolean inCopiedVtableSpace(Address vptrAddress) { + if (vptrAddress == null) { + return false; + } if (vptrAddress.greaterThan(mdRegionBaseAddress) && vptrAddress.lessThanOrEqual(mdRegionEndAddress)) { return true; diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java openjdk-lts-11.0.21+9/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java --- openjdk-lts-11.0.20.1+1/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -130,6 +130,7 @@ private static Type intxType; private static Type uintxType; private static Type sizetType; + private static Type uint64tType; private static CIntegerType boolType; private Boolean sharingEnabled; private Boolean compressedOopsEnabled; @@ -231,6 +232,50 @@ return addr.getCIntegerAt(0, sizetType.getSize(), true); } + public boolean isCcstr() { + return type.equals("ccstr"); + } + + public String getCcstr() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isCcstr(), "not a ccstr flag!"); + } + return CStringUtilities.getString(addr.getAddressAt(0)); + } + + public boolean isCcstrlist() { + return type.equals("ccstrlist"); + } + + public String getCcstrlist() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isCcstrlist(), "not a ccstrlist flag!"); + } + return CStringUtilities.getString(addr.getAddressAt(0)); + } + + public boolean isDouble() { + return type.equals("double"); + } + + public double getDouble() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isDouble(), "not a double flag!"); + } + return addr.getJDoubleAt(0); + } + + public boolean isUint64t() { + return type.equals("uint64_t"); + } + + public long getUint64t() { + if (Assert.ASSERTS_ENABLED) { + Assert.that(isUint64t(), "not an uint64_t flag!"); + } + return addr.getCIntegerAt(0, uint64tType.getSize(), true); + } + public String getValue() { if (isBool()) { return Boolean.toString(getBool()); @@ -241,11 +286,27 @@ } else if (isIntx()) { return Long.toString(getIntx()); } else if (isUIntx()) { - return Long.toString(getUIntx()); + return Long.toUnsignedString(getUIntx()); } else if (isSizet()) { - return Long.toString(getSizet()); + return Long.toUnsignedString(getSizet()); + } else if (isCcstr()) { + var str = getCcstr(); + if (str != null) { + str = "\"" + str + "\""; + } + return str; + } else if (isCcstrlist()) { + var str = getCcstrlist(); + if (str != null) { + str = "\"" + str + "\""; + } + return str; + } else if (isDouble()) { + return Double.toString(getDouble()); + } else if (isUint64t()) { + return Long.toUnsignedString(getUint64t()); } else { - return null; + throw new WrongTypeException("Unknown type: " + type + " (" + name + ")"); } } }; @@ -383,6 +444,7 @@ intxType = db.lookupType("intx"); uintxType = db.lookupType("uintx"); sizetType = db.lookupType("size_t"); + uint64tType = db.lookupType("uint64_t"); boolType = (CIntegerType) db.lookupType("bool"); minObjAlignmentInBytes = getObjectAlignmentInBytes(); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java openjdk-lts-11.0.21+9/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java --- openjdk-lts-11.0.20.1+1/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -293,6 +293,8 @@ if (f != null) { if (f.isBool()) { return f.getBool()? 1L : 0L; + } else if (f.isUIntx() || f.isSizet() || f.isUint64t()) { + return Long.parseUnsignedLong(f.getValue()); } else { return Long.parseLong(f.getValue()); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Binding.java 2023-10-06 05:33:33.000000000 +0000 @@ -14,7 +14,7 @@ * @see Macro * @see Reference * @see Widget - * @see org.jline.keymap.KeyMap + * @see jdk.internal.org.jline.keymap.KeyMap * * @author Guillaume Nodet */ diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Candidate.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,6 +24,7 @@ private final String suffix; private final String key; private final boolean complete; + private final int sort; /** * Simple constructor with only a single String as an argument. @@ -31,7 +32,7 @@ * @param value the candidate */ public Candidate(String value) { - this(value, value, null, null, null, null, true); + this(value, value, null, null, null, null, true, 0); } /** @@ -44,8 +45,9 @@ * @param suffix the suffix * @param key the key * @param complete the complete flag + * @param sort the sort flag */ - public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete) { + public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete, int sort) { this.value = Objects.requireNonNull(value); this.displ = Objects.requireNonNull(displ); this.group = group; @@ -53,6 +55,22 @@ this.suffix = suffix; this.key = key; this.complete = complete; + this.sort = sort; + } + + /** + * Constructs a new Candidate. + * + * @param value the value + * @param displ the display string + * @param group the group + * @param descr the description + * @param suffix the suffix + * @param key the key + * @param complete the complete flag + */ + public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete) { + this(value, displ, group, descr, suffix, key, complete, 0); } /** @@ -133,9 +151,36 @@ return complete; } + /** + * Integer used to override default sort logic. + * @return the sort int + */ + public int sort() { + return sort; + } + + @Override public int compareTo(Candidate o) { - return value.compareTo(o.value); + // If both candidates have same sort, use default behavior + if( sort == o.sort() ) { + return value.compareTo(o.value); + } else { + return Integer.compare(sort, o.sort()); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Candidate candidate = (Candidate) o; + return Objects.equals(value, candidate.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); } @Override diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletingParsedLine.java 2023-10-06 05:33:33.000000000 +0000 @@ -10,7 +10,7 @@ /** * An extension of {@link ParsedLine} that, being aware of the quoting and escaping rules - * of the {@link org.jline.reader.Parser} that produced it, knows if and how a completion candidate + * of the {@link jdk.internal.org.jline.reader.Parser} that produced it, knows if and how a completion candidate * should be escaped/quoted. * * @author Eric Bottard diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/CompletionMatcher.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,7 +29,7 @@ /** * * @param candidates list of candidates - * @return a map of candidates that completion matcher matches + * @return a list of candidates that completion matcher matches */ List matches(List candidates); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Highlighter.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2019, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -14,7 +14,28 @@ public interface Highlighter { + /** + * Highlight buffer + * @param reader LineReader + * @param buffer the buffer to be highlighted + * @return highlighted buffer + */ AttributedString highlight(LineReader reader, String buffer); - public void setErrorPattern(Pattern errorPattern); - public void setErrorIndex(int errorIndex); + + /** + * Refresh highlight configuration + */ + default void refresh(LineReader reader) {} + + /** + * Set error pattern to be highlighted + * @param errorPattern error pattern to be highlighted + */ + void setErrorPattern(Pattern errorPattern); + + /** + * Set error index to be highlighted + * @param errorIndex error index to be highlighted + */ + void setErrorIndex(int errorIndex); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/History.java 2023-10-06 05:33:33.000000000 +0000 @@ -61,12 +61,13 @@ void append(Path file, boolean incremental) throws IOException; /** - * Read history from the file. If incremental only the events that are not contained within the internal list are added. + * Read history from the file. If checkDuplicates is true only the events that + * are not contained within the internal list are added. * @param file History file - * @param incremental If true incremental read operation is performed. + * @param checkDuplicates If true, duplicate history entries will be discarded * @throws IOException if a problem occurs */ - void read(Path file, boolean incremental) throws IOException; + void read(Path file, boolean checkDuplicates) throws IOException; /** * Purge history. diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/FileNameCompleter.java 2023-10-06 05:33:33.000000000 +0000 @@ -41,7 +41,7 @@ * @author Marc Prud'hommeaux * @author Jason Dillon * @since 2.3 - * @deprecated use org.jline.builtins.Completers$FileNameCompleter instead + * @deprecated use jdk.internal.org.jline.builtins.Completers$FileNameCompleter instead */ @Deprecated public class FileNameCompleter implements Completer diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/completer/SystemCompleter.java 2023-10-06 05:33:33.000000000 +0000 @@ -67,7 +67,7 @@ if (cmd != null) { if (completers.containsKey(cmd)) { out = cmd; - } else if (aliasCommand.containsKey(cmd)) { + } else { out = aliasCommand.get(cmd); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/CompletionMatcherImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -54,7 +54,7 @@ break; } } - return !matching.isEmpty() ? matching.entrySet().stream().flatMap(e -> e.getValue().stream()).collect(Collectors.toList()) + return !matching.isEmpty() ? matching.entrySet().stream().flatMap(e -> e.getValue().stream()).distinct().collect(Collectors.toList()) : new ArrayList<>(); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/DefaultParser.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,6 +27,27 @@ ANGLE // <> } + public static class BlockCommentDelims { + private final String start; + private final String end; + public BlockCommentDelims(String start, String end) { + if (start == null || end == null + || start.isEmpty() || end.isEmpty() || start.equals(end)) { + throw new IllegalArgumentException("Bad block comment delimiter!"); + } + this.start = start; + this.end = end; + } + + public String getStart() { + return start; + } + + public String getEnd() { + return end; + } + } + private char[] quoteChars = {'\'', '"'}; private char[] escapeChars = {'\\'}; @@ -39,6 +60,10 @@ private char[] closingBrackets = null; + private String[] lineCommentDelims = null; + + private BlockCommentDelims blockCommentDelims = null; + private String regexVariable = "[a-zA-Z_]+[a-zA-Z0-9_-]*((\\.|\\['|\\[\"|\\[)[a-zA-Z0-9_-]*(|']|\"]|]))?"; private String regexCommand = "[:]?[a-zA-Z]+[a-zA-Z0-9_-]*"; private int commandGroup = 4; @@ -47,6 +72,16 @@ // Chainable setters // + public DefaultParser lineCommentDelims(final String[] lineCommentDelims) { + this.lineCommentDelims = lineCommentDelims; + return this; + } + + public DefaultParser blockCommentDelims(final BlockCommentDelims blockCommentDelims) { + this.blockCommentDelims = blockCommentDelims; + return this; + } + public DefaultParser quoteChars(final char[] chars) { this.quoteChars = chars; return this; @@ -107,6 +142,22 @@ return this.escapeChars; } + public void setLineCommentDelims(String[] lineCommentDelims) { + this.lineCommentDelims = lineCommentDelims; + } + + public String[] getLineCommentDelims() { + return this.lineCommentDelims; + } + + public void setBlockCommentDelims(BlockCommentDelims blockCommentDelims) { + this.blockCommentDelims = blockCommentDelims; + } + + public BlockCommentDelims getBlockCommentDelims() { + return blockCommentDelims; + } + public void setEofOnUnclosedQuote(boolean eofOnUnclosedQuote) { this.eofOnUnclosedQuote = eofOnUnclosedQuote; } @@ -225,6 +276,11 @@ int rawWordStart = 0; BracketChecker bracketChecker = new BracketChecker(cursor); boolean quotedWord = false; + boolean lineCommented = false; + boolean blockCommented = false; + boolean blockCommentInRightOrder = true; + final String blockCommentEnd = blockCommentDelims == null ? null : blockCommentDelims.end; + final String blockCommentStart = blockCommentDelims == null ? null : blockCommentDelims.start; for (int i = 0; (line != null) && (i < line.length()); i++) { // once we reach the cursor, set the @@ -237,7 +293,7 @@ rawWordCursor = i - rawWordStart; } - if (quoteStart < 0 && isQuoteChar(line, i)) { + if (quoteStart < 0 && isQuoteChar(line, i) && !lineCommented && !blockCommented) { // Start a quote block quoteStart = i; if (current.length()==0) { @@ -258,17 +314,40 @@ quoteStart = -1; quotedWord = false; } else if (quoteStart < 0 && isDelimiter(line, i)) { - // Delimiter - if (current.length() > 0) { - words.add(current.toString()); - current.setLength(0); // reset the arg - if (rawWordCursor >= 0 && rawWordLength < 0) { - rawWordLength = i - rawWordStart; + if (lineCommented) { + if (isCommentDelim(line, i, System.lineSeparator())) { + lineCommented = false; + } + } else if (blockCommented) { + if (isCommentDelim(line, i, blockCommentEnd)) { + blockCommented = false; } + } else { + // Delimiter + rawWordLength = handleDelimiterAndGetRawWordLength(current, words, rawWordStart, rawWordCursor, rawWordLength, i); + rawWordStart = i + 1; } - rawWordStart = i + 1; } else { - if (!isEscapeChar(line, i)) { + if (quoteStart < 0 && !blockCommented && (lineCommented || isLineCommentStarted(line, i))) { + lineCommented = true; + } else if (quoteStart < 0 && !lineCommented + && (blockCommented || isCommentDelim(line, i, blockCommentStart))) { + if (blockCommented) { + if (blockCommentEnd != null && isCommentDelim(line, i, blockCommentEnd)) { + blockCommented = false; + i += blockCommentEnd.length() - 1; + } + } else { + blockCommented = true; + rawWordLength = handleDelimiterAndGetRawWordLength(current, words, rawWordStart, rawWordCursor, rawWordLength, i); + i += blockCommentStart == null ? 0 : blockCommentStart.length() - 1; + rawWordStart = i + 1; + } + } else if (quoteStart < 0 && !lineCommented + && isCommentDelim(line, i, blockCommentEnd)) { + current.append(line.charAt(i)); + blockCommentInRightOrder = false; + } else if (!isEscapeChar(line, i)) { current.append(line.charAt(i)); if (quoteStart < 0) { bracketChecker.check(line, i); @@ -301,6 +380,14 @@ throw new EOFError(-1, -1, "Missing closing quote", line.charAt(quoteStart) == '\'' ? "quote" : "dquote"); } + if (blockCommented) { + throw new EOFError(-1, -1, "Missing closing block comment delimiter", + "add: " + blockCommentEnd); + } + if (!blockCommentInRightOrder) { + throw new EOFError(-1, -1, "Missing opening block comment delimiter", + "missing: " + blockCommentStart); + } if (bracketChecker.isClosingBracketMissing() || bracketChecker.isOpeningBracketMissing()) { String message = null; String missing = null; @@ -333,6 +420,17 @@ return !isQuoted(buffer, pos) && !isEscaped(buffer, pos) && isDelimiterChar(buffer, pos); } + private int handleDelimiterAndGetRawWordLength(StringBuilder current, List words, int rawWordStart, int rawWordCursor, int rawWordLength, int pos) { + if (current.length() > 0) { + words.add(current.toString()); + current.setLength(0); // reset the arg + if (rawWordCursor >= 0 && rawWordLength < 0) { + return pos - rawWordStart; + } + } + return rawWordLength; + } + public boolean isQuoted(final CharSequence buffer, final int pos) { return false; } @@ -348,6 +446,36 @@ } } } + return false; + } + + private boolean isCommentDelim(final CharSequence buffer, final int pos, final String pattern) { + if (pos < 0) { + return false; + } + + if (pattern != null) { + final int length = pattern.length(); + if (length <= buffer.length() - pos) { + for (int i = 0; i < length; i++) { + if (pattern.charAt(i) != buffer.charAt(pos + i)) { + return false; + } + } + return true; + } + } + return false; + } + + public boolean isLineCommentStarted(final CharSequence buffer, final int pos) { + if (lineCommentDelims != null) { + for (String comment: lineCommentDelims) { + if (isCommentDelim(buffer, pos, comment)) { + return true; + } + } + } return false; } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/history/DefaultHistory.java 2023-10-06 05:33:33.000000000 +0000 @@ -97,14 +97,14 @@ } @Override - public void read(Path file, boolean incremental) throws IOException { + public void read(Path file, boolean checkDuplicates) throws IOException { Path path = file != null ? file : getPath(); if (path != null) { try { if (Files.exists(path)) { Log.trace("Reading history from: ", path); try (BufferedReader reader = Files.newBufferedReader(path)) { - reader.lines().forEach(line -> addHistoryLine(path, line, incremental)); + reader.lines().forEach(line -> addHistoryLine(path, line, checkDuplicates)); setHistoryFileData(path, new HistoryFileData(items.size(), offset + items.size())); maybeResize(); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/impl/LineReaderImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2022, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -281,7 +281,7 @@ int candidateStartPosition = 0; public LineReaderImpl(Terminal terminal) throws IOException { - this(terminal, null, null); + this(terminal, terminal.getName(), null); } public LineReaderImpl(Terminal terminal, String appName) throws IOException { @@ -633,7 +633,8 @@ callWidget(CALLBACK_INIT); - undo.newState(buf.copy()); + if (!isSet(Option.DISABLE_UNDO)) + undo.newState(buf.copy()); // Draw initial prompt redrawLine(); @@ -679,7 +680,7 @@ if (!w.apply()) { beep(); } - if (!isUndo && copy != null && buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) + if (!isSet(Option.DISABLE_UNDO) && !isUndo && copy != null && buf.length() <= getInt(FEATURES_MAX_BUFFER_SIZE, DEFAULT_FEATURES_MAX_BUFFER_SIZE) && !copy.toString().equals(buf.toString())) { undo.newState(buf.copy()); } @@ -739,8 +740,8 @@ } } finally { lock.unlock(); + startedReading.set(false); } - startedReading.set(false); } } @@ -1082,18 +1083,18 @@ if (isSet(Option.BRACKETED_PASTE)) { terminal.writer().write(BRACKETED_PASTE_OFF); } - Constructor ctor = Class.forName("org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); + Constructor ctor = Class.forName("jdk.internal.org.jline.builtins.Nano").getConstructor(Terminal.class, File.class); Editor editor = (Editor) ctor.newInstance(terminal, new File(file.getParent())); editor.setRestricted(true); editor.open(Collections.singletonList(file.getName())); editor.run(); - BufferedReader br = new BufferedReader(new FileReader(file)); - String line; - commandsBuffer.clear(); - while ((line = br.readLine()) != null) { - commandsBuffer.add(line); + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + commandsBuffer.clear(); + while ((line = br.readLine()) != null) { + commandsBuffer.add(line); + } } - br.close(); } // @@ -3595,9 +3596,9 @@ File file = null; try { file = File.createTempFile("jline-execute-", null); - FileWriter writer = new FileWriter(file); - writer.write(buf.toString()); - writer.close(); + try (FileWriter writer = new FileWriter(file)) { + writer.write(buf.toString()); + } editAndAddInBuffer(file); } catch (Exception e) { e.printStackTrace(terminal.writer()); @@ -3796,6 +3797,9 @@ Status status = Status.getStatus(terminal, false); if (status != null) { + if (terminal.getType().startsWith(AbstractWindowsTerminal.TYPE_WINDOWS)) { + status.resize(); + } status.redraw(); } @@ -3947,7 +3951,8 @@ StringBuilder sb = new StringBuilder(); for (char c: buffer.replace("\\", "\\\\").toCharArray()) { if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '*' - || c == '$' || c == '.' || c == '?' || c == '+') { + || c == '$' || c == '.' || c == '?' || c == '+' || c == '|' || c == '<' || c == '>' || c == '!' + || c == '-') { sb.append('\\'); } sb.append(c); @@ -4520,7 +4525,7 @@ } } - private CompletingParsedLine wrap(ParsedLine line) { + protected static CompletingParsedLine wrap(ParsedLine line) { if (line instanceof CompletingParsedLine) { return (CompletingParsedLine) line; } else { @@ -4625,6 +4630,11 @@ return size.getRows() - (status != null ? status.size() : 0); } + private int visibleDisplayRows() { + Status status = Status.getStatus(terminal, false); + return terminal.getSize().getRows() - (status != null ? status.size() : 0); + } + private int promptLines() { AttributedString text = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); return text.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); @@ -5070,18 +5080,19 @@ protected PostResult computePost(List possible, Candidate selection, List ordered, String completed, Function wcwidth, int width, boolean autoGroup, boolean groupName, boolean rowsFirst) { List strings = new ArrayList<>(); + boolean customOrder = possible.stream().anyMatch(c -> c.sort() != 0); if (groupName) { Comparator groupComparator = getGroupComparator(); - Map> sorted; + Map> sorted; sorted = groupComparator != null ? new TreeMap<>(groupComparator) : new LinkedHashMap<>(); for (Candidate cand : possible) { String group = cand.group(); sorted.computeIfAbsent(group != null ? group : "", s -> new LinkedHashMap<>()) - .put(cand.value(), cand); + .put((customOrder ? cand.sort() : cand.value()), cand); } - for (Map.Entry> entry : sorted.entrySet()) { + for (Map.Entry> entry : sorted.entrySet()) { String group = entry.getKey(); if (group.isEmpty() && sorted.size() > 1) { group = getOthersGroupName(); @@ -5096,13 +5107,13 @@ } } else { Set groups = new LinkedHashSet<>(); - TreeMap sorted = new TreeMap<>(); + TreeMap sorted = new TreeMap<>(); for (Candidate cand : possible) { String group = cand.group(); if (group != null) { groups.add(group); } - sorted.put(cand.value(), cand); + sorted.put((customOrder ? cand.sort() : cand.value()), cand); } if (autoGroup) { strings.addAll(groups); @@ -5129,7 +5140,7 @@ this.startPos = startPos; endLine = line.substring(line.lastIndexOf('\n') + 1); boolean first = true; - while (endLine.length() + (first ? startPos : 0) > width) { + while (endLine.length() + (first ? startPos : 0) > width && width > 0) { if (first) { endLine = endLine.substring(width - startPos); } else { @@ -5207,7 +5218,7 @@ AttributedStringBuilder sb = new AttributedStringBuilder(); if (listSize > 0) { if (isSet(Option.AUTO_MENU_LIST) - && listSize < Math.min(getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), displayRows() - promptLines())) { + && listSize < Math.min(getInt(MENU_LIST_MAX, DEFAULT_MENU_LIST_MAX), visibleDisplayRows() - promptLines())) { maxWidth = Math.max(maxWidth, MENU_LIST_WIDTH); sb.tabs(Math.max(Math.min(candidateStartPosition, width - maxWidth - 1), 1)); width = maxWidth + 2; diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReaderBuilder.java 2023-10-06 05:33:33.000000000 +0000 @@ -118,6 +118,12 @@ throw new IOError(e); } } + + String appName = this.appName; + if (null == appName) { + appName = terminal.getName(); + } + LineReaderImpl reader = new LineReaderImpl(terminal, appName, variables); if (history != null) { reader.setHistory(history); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/LineReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -352,7 +352,7 @@ String AMBIGUOUS_BINDING = "ambiguous-binding"; /** - * Columns separated list of patterns that will not be saved in history. + * Colon separated list of patterns that will not be saved in history. */ String HISTORY_IGNORE = "history-ignore"; @@ -467,6 +467,9 @@ /** Show command options tab completion candidates for zero length word */ EMPTY_WORD_OPTIONS(true), + + /** Disable the undo feature */ + DISABLE_UNDO ; private final boolean def; @@ -699,7 +702,7 @@ void runMacro(String macro); /** - * Read a mouse event when the {@link org.jline.utils.InfoCmp.Capability#key_mouse} sequence + * Read a mouse event when the {@link jdk.internal.org.jline.utils.InfoCmp.Capability#key_mouse} sequence * has just been read on the input stream. * Compared to {@link Terminal#readMouseEvent()}, this method takes into account keys * that have been pushed back using {@link #runMacro(String)}. diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/reader/Parser.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -12,8 +12,8 @@ import java.util.regex.Pattern; public interface Parser { - static final String REGEX_VARIABLE = "[a-zA-Z_]{1,}[a-zA-Z0-9_-]*"; - static final String REGEX_COMMAND = "[:]{0,1}[a-zA-Z]{1,}[a-zA-Z0-9_-]*"; + String REGEX_VARIABLE = "[a-zA-Z_]+[a-zA-Z0-9_-]*"; + String REGEX_COMMAND = "[:]?[a-zA-Z]+[a-zA-Z0-9_-]*"; ParsedLine parse(String line, int cursor, ParseContext context) throws SyntaxError; @@ -34,7 +34,7 @@ } default String getCommand(final String line) { - String out = ""; + String out; Pattern patternCommand = Pattern.compile("^\\s*" + REGEX_VARIABLE + "=(" + REGEX_COMMAND + ")(\\s+|$)"); Matcher matcher = patternCommand.matcher(line); if (matcher.find()) { @@ -68,7 +68,7 @@ /** Parsed words will have all characters present in input line * including quotes and escape chars. - * May throw EOFError in which case we have incomplete input. + * We should tolerate and ignore errors. */ SPLIT_LINE, diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractPty.java 2023-10-06 05:33:33.000000000 +0000 @@ -86,11 +86,6 @@ } } - @Override - public int readBuffered(byte[] b) throws IOException { - return in.read(b); - } - private void setNonBlocking() { if (current == null || current.getControlChar(Attributes.ControlChar.VMIN) != 0 diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/AbstractWindowsTerminal.java 2023-10-06 05:33:33.000000000 +0000 @@ -81,8 +81,8 @@ protected boolean focusTracking = false; private volatile boolean closing; - public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException { - super(name, type, selectCharset(encoding, codepage), signalHandler); + public AbstractWindowsTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException { + super(name, type, encoding, signalHandler); NonBlockingPumpReader reader = NonBlocking.nonBlockingPumpReader(); this.slaveInputPipe = reader.getWriter(); this.input = inputStreamWrapper.apply(NonBlocking.nonBlockingStream(reader, encoding())); @@ -116,35 +116,6 @@ } } - private static Charset selectCharset(Charset encoding, int codepage) { - if (encoding != null) { - return encoding; - } - - if (codepage >= 0) { - return getCodepageCharset(codepage); - } - - // Use UTF-8 as default - return StandardCharsets.UTF_8; - } - - private static Charset getCodepageCharset(int codepage) { - //http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html - if (codepage == UTF8_CODE_PAGE) { - return StandardCharsets.UTF_8; - } - String charsetMS = "ms" + codepage; - if (Charset.isSupported(charsetMS)) { - return Charset.forName(charsetMS); - } - String charsetCP = "cp" + codepage; - if (Charset.isSupported(charsetCP)) { - return Charset.forName(charsetCP); - } - return Charset.defaultCharset(); - } - @Override public SignalHandler handle(Signal signal, SignalHandler handler) { SignalHandler prev = super.handle(signal, handler); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/Diag.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2022, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl; + +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.util.ServiceLoader; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.concurrent.TimeUnit; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.OSUtils; + +public class Diag { + + public static void main(String[] args) { + diag(System.out); + } + + static void diag(PrintStream out) { + out.println("System properties"); + out.println("================="); + out.println("os.name = " + System.getProperty("os.name")); + out.println("OSTYPE = " + System.getenv("OSTYPE")); + out.println("MSYSTEM = " + System.getenv("MSYSTEM")); + out.println("PWD = " + System.getenv("PWD")); + out.println("ConEmuPID = " + System.getenv("ConEmuPID")); + out.println("WSL_DISTRO_NAME = " + System.getenv("WSL_DISTRO_NAME")); + out.println("WSL_INTEROP = " + System.getenv("WSL_INTEROP")); + out.println(); + + out.println("OSUtils"); + out.println("================="); + out.println("IS_WINDOWS = " + OSUtils.IS_WINDOWS); + out.println("IS_CYGWIN = " + OSUtils.IS_CYGWIN); + out.println("IS_MSYSTEM = " + OSUtils.IS_MSYSTEM); + out.println("IS_WSL = " + OSUtils.IS_WSL); + out.println("IS_WSL1 = " + OSUtils.IS_WSL1); + out.println("IS_WSL2 = " + OSUtils.IS_WSL2); + out.println("IS_CONEMU = " + OSUtils.IS_CONEMU); + out.println("IS_OSX = " + OSUtils.IS_OSX); + out.println(); + + out.println("JnaSupport"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("jna"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("JNA support not available: " + t); + } + out.println(); + + out.println("JansiSupport"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("jansi"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("Jansi support not available: " + t); + } + out.println(); + + // Exec + out.println("Exec Support"); + out.println("================="); + try { + TerminalProvider provider = TerminalProvider.load("exec"); + testProvider(out, provider); + } catch (Throwable t) { + out.println("Exec support not available: " + t); + } + } + + private static void testProvider(PrintStream out, TerminalProvider provider) { + try { + out.println("StdIn stream = " + provider.isSystemStream(TerminalProvider.Stream.Input)); + out.println("StdOut stream = " + provider.isSystemStream(TerminalProvider.Stream.Output)); + out.println("StdErr stream = " + provider.isSystemStream(TerminalProvider.Stream.Error)); + } catch (Throwable t2) { + out.println("Unable to check stream: " + t2); + } + try { + out.println("StdIn stream name = " + provider.systemStreamName(TerminalProvider.Stream.Input)); + out.println("StdOut stream name = " + provider.systemStreamName(TerminalProvider.Stream.Output)); + out.println("StdErr stream name = " + provider.systemStreamName(TerminalProvider.Stream.Error)); + } catch (Throwable t2) { + out.println("Unable to check stream names: " + t2); + } + try (Terminal terminal = provider.sysTerminal("diag", "xterm", false, StandardCharsets.UTF_8, + false, Terminal.SignalHandler.SIG_DFL, false, TerminalProvider.Stream.Output, input -> input) ) { + if (terminal != null) { + Attributes attr = terminal.enterRawMode(); + try { + out.println("Terminal size: " + terminal.getSize()); + ForkJoinTask t = new ForkJoinPool(1).submit(() -> terminal.reader().read(1) ); + int r = t.get(1000, TimeUnit.MILLISECONDS); + StringBuilder sb = new StringBuilder(); + sb.append("The terminal seems to work: "); + sb.append("terminal ").append(terminal.getClass().getName()); + if (terminal instanceof AbstractPosixTerminal) { + sb.append(" with pty ").append(((AbstractPosixTerminal) terminal).getPty().getClass().getName()); + } + out.println(sb); + } catch (Throwable t3) { + out.println("Unable to read from terminal: " + t3); + t3.printStackTrace(); + } finally { + terminal.setAttributes(attr); + } + } else { + out.println("Not supported by provider"); + } + } catch (Throwable t2) { + out.println("Unable to open terminal: " + t2); + t2.printStackTrace(); + } + } + + static S load(Class clazz) { + return ServiceLoader.load(clazz, clazz.getClassLoader()).iterator().next(); + } + +} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/exec/ExecTerminalProvider.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2022, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.impl.exec; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.impl.ExecPty; +import jdk.internal.org.jline.terminal.impl.ExternalTerminal; +import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; +import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; +import jdk.internal.org.jline.utils.ExecHelper; +import jdk.internal.org.jline.utils.OSUtils; + +public class ExecTerminalProvider implements TerminalProvider +{ + + public String name() { + return "exec"; + } + + public Pty current(Stream consoleStream) throws IOException { + return ExecPty.current(consoleStream); + } + + @Override + public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException { + if (OSUtils.IS_WINDOWS) { + return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + } else { + return posixSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper ); + } + } + + public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper ) throws IOException { + if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { + Pty pty = current(consoleStream); + return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); + } else { + return null; + } + } + + public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, + boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException { + Pty pty = current(consoleStream); + return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler, inputStreamWrapper); + } + + @Override + public Terminal newTerminal(String name, String type, InputStream in, OutputStream out, + Charset encoding, Terminal.SignalHandler signalHandler, boolean paused, + Attributes attributes, Size size) throws IOException + { + return new ExternalTerminal(name, type, in, out, encoding, signalHandler, paused, attributes, size); + } + + @Override + public boolean isSystemStream(Stream stream) { + try { + return isWindowsSystemStream(stream) || isPosixSystemStream(stream); + } catch (Throwable t) { + return false; + } + } + + public boolean isWindowsSystemStream(Stream stream) { + return systemStreamName( stream ) != null; + } + + public boolean isPosixSystemStream(Stream stream) { + try { + Process p = new ProcessBuilder(OSUtils.TEST_COMMAND, "-t", Integer.toString(stream.ordinal())) + .inheritIO().start(); + return p.waitFor() == 0; + } catch (Throwable t) { + // ignore + } + return false; + } + + @Override + public String systemStreamName(Stream stream) { + try { + ProcessBuilder.Redirect input = stream == Stream.Input + ? ProcessBuilder.Redirect.INHERIT + : getRedirect(stream == Stream.Output ? FileDescriptor.out : FileDescriptor.err); + Process p = new ProcessBuilder(OSUtils.TTY_COMMAND).redirectInput(input).start(); + String result = ExecHelper.waitAndCapture(p); + if (p.exitValue() == 0) { + return result.trim(); + } + } catch (Throwable t) { + // ignore + } + return null; + } + + private ProcessBuilder.Redirect getRedirect(FileDescriptor fd) throws ReflectiveOperationException { + // This is not really allowed, but this is the only way to redirect the output or error stream + // to the input. This is definitely not something you'd usually want to do, but in the case of + // the `tty` utility, it provides a way to get + Class rpi = Class.forName("java.lang.ProcessBuilder$RedirectPipeImpl"); + Constructor cns = rpi.getDeclaredConstructor(); + cns.setAccessible(true); + ProcessBuilder.Redirect input = (ProcessBuilder.Redirect) cns.newInstance(); + Field f = rpi.getDeclaredField("fd"); + f.setAccessible(true); + f.set(input, fd); + return input; + } +} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/ExecPty.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,6 +26,7 @@ import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.Attributes.OutputFlag; import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.terminal.spi.Pty; import jdk.internal.org.jline.utils.OSUtils; @@ -34,20 +35,23 @@ public class ExecPty extends AbstractPty implements Pty { private final String name; - private final boolean system; + private final TerminalProvider.Stream console; - public static Pty current() throws IOException { + public static Pty current(TerminalProvider.Stream console) throws IOException { try { String result = exec(true, OSUtils.TTY_COMMAND); - return new ExecPty(result.trim(), true); + if (console != TerminalProvider.Stream.Output && console != TerminalProvider.Stream.Error) { + throw new IllegalArgumentException("console should be Output or Error: " + console); + } + return new ExecPty(result.trim(), console); } catch (IOException e) { throw new IOException("Not a tty", e); } } - protected ExecPty(String name, boolean system) { + protected ExecPty(String name, TerminalProvider.Stream console) { this.name = name; - this.system = system; + this.console = console; } @Override @@ -70,16 +74,18 @@ @Override protected InputStream doGetSlaveInput() throws IOException { - return system + return console != null ? new FileInputStream(FileDescriptor.in) : new FileInputStream(getName()); } @Override public OutputStream getSlaveOutput() throws IOException { - return system + return console == TerminalProvider.Stream.Output ? new FileOutputStream(FileDescriptor.out) - : new FileOutputStream(getName()); + : console == TerminalProvider.Stream.Error + ? new FileOutputStream(FileDescriptor.err) + : new FileOutputStream(getName()); } @Override @@ -93,23 +99,11 @@ List commands = getFlagsToSet(attr, getAttr()); if (!commands.isEmpty()) { commands.add(0, OSUtils.STTY_COMMAND); - if (!system) { + if (console == null) { commands.add(1, OSUtils.STTY_F_OPTION); commands.add(2, getName()); } - try { - exec(system, commands.toArray(new String[commands.size()])); - } catch (IOException e) { - // Handle partial failures with GNU stty, see #97 - if (e.toString().contains("unable to perform all requested operations")) { - commands = getFlagsToSet(attr, getAttr()); - if (!commands.isEmpty()) { - throw new IOException("Could not set the following flags: " + String.join(", ", commands), e); - } - } else { - throw e; - } - } + exec(console != null, commands.toArray(new String[0])); } } @@ -171,7 +165,7 @@ } protected String doGetConfig() throws IOException { - return system + return console != null ? exec(true, OSUtils.STTY_COMMAND, "-a") : exec(false, OSUtils.STTY_COMMAND, OSUtils.STTY_F_OPTION, getName(), "-a"); } @@ -280,7 +274,7 @@ @Override public void setSize(Size size) throws IOException { - if (system) { + if (console != null) { exec(true, OSUtils.STTY_COMMAND, "columns", Integer.toString(size.getColumns()), @@ -296,7 +290,7 @@ @Override public String toString() { - return "ExecPty[" + getName() + (system ? ", system]" : "]"); + return "ExecPty[" + getName() + (console != null ? ", system]" : "]"); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixPtyTerminal.java 2023-10-06 05:33:33.000000000 +0000 @@ -15,7 +15,6 @@ import java.io.PrintWriter; import java.nio.charset.Charset; import java.util.Objects; -import java.util.concurrent.atomic.AtomicBoolean; import jdk.internal.org.jline.terminal.spi.Pty; import jdk.internal.org.jline.utils.ClosedException; @@ -143,10 +142,10 @@ } } - private class InputStreamWrapper extends NonBlockingInputStream { + private static class InputStreamWrapper extends NonBlockingInputStream { private final NonBlockingInputStream in; - private final AtomicBoolean closed = new AtomicBoolean(); + private volatile boolean closed; protected InputStreamWrapper(NonBlockingInputStream in) { this.in = in; @@ -154,7 +153,7 @@ @Override public int read(long timeout, boolean isPeek) throws IOException { - if (closed.get()) { + if (closed) { throw new ClosedException(); } return in.read(timeout, isPeek); @@ -162,7 +161,7 @@ @Override public void close() throws IOException { - closed.set(true); + closed = true; } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/impl/PosixSysTerminal.java 2023-10-06 05:33:33.000000000 +0000 @@ -16,6 +16,7 @@ import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import jdk.internal.org.jline.utils.NonBlocking; import jdk.internal.org.jline.terminal.spi.Pty; @@ -34,11 +35,12 @@ protected final Map nativeHandlers = new HashMap<>(); protected final Task closer; - public PosixSysTerminal(String name, String type, Pty pty, InputStream in, OutputStream out, Charset encoding, - boolean nativeSignals, SignalHandler signalHandler) throws IOException { + public PosixSysTerminal(String name, String type, Pty pty, Charset encoding, + boolean nativeSignals, SignalHandler signalHandler, + Function inputStreamWrapper) throws IOException { super(name, type, pty, encoding, signalHandler); - this.input = NonBlocking.nonBlocking(getName(), in); - this.output = out; + this.input = NonBlocking.nonBlocking(getName(), inputStreamWrapper.apply(pty.getSlaveInput())); + this.output = pty.getSlaveOutput(); this.reader = NonBlocking.nonBlocking(getName(), input, encoding()); this.writer = new PrintWriter(new OutputStreamWriter(output, encoding())); parseInfoCmp(); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JansiSupport.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.spi; - -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.Terminal; - -import java.io.IOException; -import java.nio.charset.Charset; - -public interface JansiSupport { - - Pty current() throws IOException; - - Pty open(Attributes attributes, Size size) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException; - - boolean isWindowsConsole(); - - boolean isConsoleOutput(); - - boolean isConsoleInput(); -} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/JnaSupport.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2002-2020, the original author or authors. - * - * This software is distributable under the BSD license. See the terms of the - * BSD license in the documentation provided with this software. - * - * https://opensource.org/licenses/BSD-3-Clause - */ -package jdk.internal.org.jline.terminal.spi; - -import jdk.internal.org.jline.terminal.Attributes; -import jdk.internal.org.jline.terminal.Size; -import jdk.internal.org.jline.terminal.Terminal; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; -import java.util.function.Function; - -public interface JnaSupport { - - Pty current() throws IOException; - - Pty open(Attributes attributes, Size size) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException; - - Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, Function inputStreamWrapper) throws IOException; - - boolean isWindowsConsole(); - - boolean isConsoleOutput(); - - boolean isConsoleInput(); -} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/spi/TerminalProvider.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.terminal.spi; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.function.Function; + +import jdk.internal.org.jline.terminal.Attributes; +import jdk.internal.org.jline.terminal.Size; +import jdk.internal.org.jline.terminal.Terminal; +import jdk.internal.org.jline.terminal.impl.exec.ExecTerminalProvider; + +public interface TerminalProvider +{ + + enum Stream { + Input, + Output, + Error + } + + String name(); + + Terminal sysTerminal(String name, String type, boolean ansiPassThrough, + Charset encoding, boolean nativeSignals, + Terminal.SignalHandler signalHandler, boolean paused, + Stream consoleStream, Function inputStreamWrapper) throws IOException; + + Terminal newTerminal(String name, String type, + InputStream masterInput, OutputStream masterOutput, + Charset encoding, Terminal.SignalHandler signalHandler, + boolean paused, Attributes attributes, Size size) throws IOException; + + boolean isSystemStream(Stream stream); + + String systemStreamName(Stream stream); + + static TerminalProvider load(String name) throws IOException { + switch (name) { + case "exec": return new ExecTerminalProvider(); + case "jna": { + try { + return (TerminalProvider) Class.forName("jdk.internal.org.jline.terminal.impl.jna.JnaTerminalProvider").getConstructor().newInstance(); + } catch (ReflectiveOperationException t) { + throw new IOException(t); + } + } + } + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } + InputStream is = cl.getResourceAsStream( "META-INF/services/org/jline/terminal/provider/" + name); + if (is != null) { + Properties props = new Properties(); + try { + props.load(is); + String className = props.getProperty("class"); + if (className == null) { + throw new IOException("No class defined in terminal provider file " + name); + } + Class clazz = cl.loadClass( className ); + return (TerminalProvider) clazz.getConstructor().newInstance(); + } catch ( Exception e ) { + throw new IOException("Unable to load terminal provider " + name, e); + } + } else { + throw new IOException("Unable to find terminal provider " + name); + } + } + +} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/terminal/TerminalBuilder.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002-2020, the original author or authors. + * Copyright (c) 2002-2021, the original author or authors. * * This software is distributable under the BSD license. See the terms of the * BSD license in the documentation provided with this software. @@ -16,22 +16,24 @@ import java.io.OutputStream; import java.lang.reflect.Method; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.ServiceLoader; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import jdk.internal.org.jline.terminal.impl.AbstractPosixTerminal; import jdk.internal.org.jline.terminal.impl.AbstractTerminal; +import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal; import jdk.internal.org.jline.terminal.impl.DumbTerminal; -import jdk.internal.org.jline.terminal.impl.ExecPty; -import jdk.internal.org.jline.terminal.impl.ExternalTerminal; -import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal; -import jdk.internal.org.jline.terminal.impl.PosixSysTerminal; -import jdk.internal.org.jline.terminal.spi.JansiSupport; -import jdk.internal.org.jline.terminal.spi.JnaSupport; -import jdk.internal.org.jline.terminal.spi.Pty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; import jdk.internal.org.jline.utils.Log; import jdk.internal.org.jline.utils.OSUtils; @@ -52,6 +54,11 @@ public static final String PROP_EXEC = "org.jline.terminal.exec"; public static final String PROP_DUMB = "org.jline.terminal.dumb"; public static final String PROP_DUMB_COLOR = "org.jline.terminal.dumb.color"; + public static final String PROP_OUTPUT = "org.jline.terminal.output"; + public static final String PROP_OUTPUT_OUT = "out"; + public static final String PROP_OUTPUT_ERR = "err"; + public static final String PROP_OUTPUT_OUT_ERR = "out-err"; + public static final String PROP_OUTPUT_ERR_OUT = "err-out"; // // Other system properties controlling various jline parts @@ -61,6 +68,16 @@ public static final String PROP_COLOR_DISTANCE = "org.jline.utils.colorDistance"; public static final String PROP_DISABLE_ALTERNATE_CHARSET = "org.jline.utils.disableAlternateCharset"; + // + // Terminal output control + // + public enum SystemOutput { + SysOut, + SysErr, + SysOutOrSysErr, + SysErrOrSysOut + } + /** * Returns the default system terminal. * Terminals should be closed properly using the {@link Terminal#close()} @@ -97,6 +114,7 @@ private Charset encoding; private int codepage; private Boolean system; + private SystemOutput systemOutput; private Boolean jna; private Boolean jansi; private Boolean exec; @@ -128,6 +146,20 @@ return this; } + /** + * Indicates which standard stream should be used when displaying to the terminal. + * The default is to use the system output stream. + * Building a system terminal will fail if one of the stream specified is not linked + * to the controlling terminal. + * + * @param systemOutput The mode to choose the output stream. + * @return The builder. + */ + public TerminalBuilder systemOutput(SystemOutput systemOutput) { + this.systemOutput = systemOutput; + return this; + } + public TerminalBuilder jna(boolean jna) { this.jna = jna; return this; @@ -298,11 +330,18 @@ encoding = Charset.forName(charsetName); } } - int codepage = this.codepage; - if (codepage <= 0) { - String str = System.getProperty(PROP_CODEPAGE); - if (str != null) { - codepage = Integer.parseInt(str); + if (encoding == null) { + int codepage = this.codepage; + if (codepage <= 0) { + String str = System.getProperty(PROP_CODEPAGE); + if (str != null) { + codepage = Integer.parseInt(str); + } + } + if (codepage >= 0) { + encoding = getCodepageCharset(codepage); + } else { + encoding = StandardCharsets.UTF_8; } } String type = this.type; @@ -328,102 +367,112 @@ if (dumb == null) { dumb = getBoolean(PROP_DUMB, null); } + IllegalStateException exception = new IllegalStateException("Unable to create a terminal"); + List providers = new ArrayList<>(); + if (jna) { + try { + TerminalProvider provider = TerminalProvider.load("jna"); + providers.add(provider); + } catch (Throwable t) { + Log.debug("Unable to load JNA support: ", t); + exception.addSuppressed(t); + } + } + if (jansi) { + try { + TerminalProvider provider = TerminalProvider.load("jansi"); + providers.add(provider); + } catch (Throwable t) { + Log.debug("Unable to load JANSI support: ", t); + exception.addSuppressed(t); + } + } + if (exec) + { + try { + TerminalProvider provider = TerminalProvider.load("exec"); + providers.add(provider); + } catch (Throwable t) { + Log.debug("Unable to load EXEC support: ", t); + exception.addSuppressed(t); + } + } + + Terminal terminal = null; if ((system != null && system) || (system == null && in == null && out == null)) { - if (system != null && ((in != null && !in.equals(System.in)) || (out != null && !out.equals(System.out)))) { + if (system != null && ((in != null && !in.equals(System.in)) || + (out != null && !out.equals(System.out) && !out.equals(System.err)))) { throw new IllegalArgumentException("Cannot create a system terminal using non System streams"); } - Terminal terminal = null; - IllegalStateException exception = new IllegalStateException("Unable to create a system terminal"); - TerminalBuilderSupport tbs = new TerminalBuilderSupport(jna, jansi); - if (tbs.isConsoleInput() && tbs.isConsoleOutput()) { + if (attributes != null || size != null) { + Log.warn("Attributes and size fields are ignored when creating a system terminal"); + } + if (out != null) { + if (out.equals(System.out)) { + systemOutput = SystemOutput.SysOut; + } else if (out.equals(System.err)) { + systemOutput = SystemOutput.SysErr; + } + } + if (systemOutput == null) { + String str = System.getProperty(PROP_OUTPUT); + if (str != null) { + switch (str.trim().toLowerCase(Locale.ROOT)) { + case PROP_OUTPUT_OUT: systemOutput = SystemOutput.SysOut; break; + case PROP_OUTPUT_ERR: systemOutput = SystemOutput.SysErr; break; + case PROP_OUTPUT_OUT_ERR: systemOutput = SystemOutput.SysOutOrSysErr; break; + case PROP_OUTPUT_ERR_OUT: systemOutput = SystemOutput.SysErrOrSysOut; break; + default: + Log.debug("Unsupported value for " + PROP_OUTPUT + ": " + str + ". Supported values are: " + + String.join(", ", PROP_OUTPUT_OUT, PROP_OUTPUT_ERR, PROP_OUTPUT_OUT_ERR,PROP_OUTPUT_ERR_OUT) + + "."); + } + } + } + if (systemOutput == null) { + systemOutput = SystemOutput.SysOutOrSysErr; + } + Map system = Stream.of(TerminalProvider.Stream.values()) + .collect(Collectors.toMap(stream -> stream, stream -> providers.stream().anyMatch(p -> p.isSystemStream(stream)))); + TerminalProvider.Stream console = select(system, systemOutput); + + if (system.get(TerminalProvider.Stream.Input) && console != null) { if (attributes != null || size != null) { Log.warn("Attributes and size fields are ignored when creating a system terminal"); } - if (OSUtils.IS_WINDOWS) { - if (!OSUtils.IS_CYGWIN && !OSUtils.IS_MSYSTEM) { - boolean ansiPassThrough = OSUtils.IS_CONEMU; - if (tbs.hasJnaSupport()) { - try { - terminal = tbs.getJnaSupport().winSysTerminal(name, type, ansiPassThrough, encoding, codepage - , nativeSignals, signalHandler, paused, inputStreamWrapper); - } catch (Throwable t) { - Log.debug("Error creating JNA based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - if (terminal == null && tbs.hasJansiSupport()) { - try { - terminal = tbs.getJansiSupport().winSysTerminal(name, type, ansiPassThrough, encoding, codepage - , nativeSignals, signalHandler, paused); - } catch (Throwable t) { - Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - } else if (exec) { - // - // Cygwin support - // - try { - // Cygwin defaults to XTERM, but actually supports 256 colors, - // so if the value comes from the environment, change it to xterm-256color - if ("xterm".equals(type) && this.type == null && System.getProperty(PROP_TYPE) == null) { - type = "xterm-256color"; - } - Pty pty = tbs.getExecPty(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); - } catch (IOException e) { - // Ignore if not a tty - Log.debug("Error creating EXEC based terminal: ", e.getMessage(), e); - exception.addSuppressed(e); - } - } - if (terminal == null && !jna && !jansi && (dumb == null || !dumb)) { - throw new IllegalStateException("Unable to create a system terminal. On windows, either " - + "JNA or JANSI library is required. Make sure to add one of those in the classpath."); - } - } else { - if (tbs.hasJnaSupport()) { - try { - Pty pty = tbs.getJnaSupport().current(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); - } catch (Throwable t) { - // ignore - Log.debug("Error creating JNA based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - if (terminal == null && tbs.hasJansiSupport()) { - try { - Pty pty = tbs.getJansiSupport().current(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); - } catch (Throwable t) { - Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t); - exception.addSuppressed(t); - } - } - if (terminal == null && exec) { + boolean ansiPassThrough = OSUtils.IS_CONEMU; + // Cygwin defaults to XTERM, but actually supports 256 colors, + // so if the value comes from the environment, change it to xterm-256color + if ((OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) && "xterm".equals(type) + && this.type == null && System.getProperty(PROP_TYPE) == null) { + type = "xterm-256color"; + } + for ( TerminalProvider provider : providers) { + if (terminal == null) { try { - Pty pty = tbs.getExecPty(); - terminal = new PosixSysTerminal(name, type, pty, inputStreamWrapper.apply(pty.getSlaveInput()), pty.getSlaveOutput(), encoding, nativeSignals, signalHandler); + terminal = provider.sysTerminal(name, type, ansiPassThrough, encoding, + nativeSignals, signalHandler, paused, console, inputStreamWrapper); } catch (Throwable t) { - // Ignore if not a tty - Log.debug("Error creating EXEC based terminal: ", t.getMessage(), t); + Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t); exception.addSuppressed(t); } } } - if (terminal instanceof AbstractTerminal) { - AbstractTerminal t = (AbstractTerminal) terminal; - if (SYSTEM_TERMINAL.compareAndSet(null, t)) { - t.setOnClose(() -> SYSTEM_TERMINAL.compareAndSet(t, null)); - } else { - exception.addSuppressed(new IllegalStateException("A system terminal is already running. " + - "Make sure to use the created system Terminal on the LineReaderBuilder if you're using one " + - "or that previously created system Terminals have been correctly closed.")); - terminal.close(); - terminal = null; - } + if (terminal == null && OSUtils.IS_WINDOWS && !jna && !jansi && (dumb == null || !dumb)) { + throw new IllegalStateException("Unable to create a system terminal. On windows, either " + + "JNA or JANSI library is required. Make sure to add one of those in the classpath."); + } + } + if (terminal instanceof AbstractTerminal) { + AbstractTerminal t = (AbstractTerminal) terminal; + if (SYSTEM_TERMINAL.compareAndSet(null, t)) { + t.setOnClose(() -> SYSTEM_TERMINAL.compareAndSet(t, null)); + } else { + exception.addSuppressed(new IllegalStateException("A system terminal is already running. " + + "Make sure to use the created system Terminal on the LineReaderBuilder if you're using one " + + "or that previously created system Terminals have been correctly closed.")); + terminal.close(); + terminal = null; } } if (terminal == null && (dumb == null || dumb)) { @@ -433,7 +482,8 @@ color = getBoolean(PROP_DUMB_COLOR, false); // detect emacs using the env variable if (!color) { - color = System.getenv("INSIDE_EMACS") != null; + String emacs = System.getenv("INSIDE_EMACS"); + color = emacs != null && emacs.contains("comint"); } // detect Intellij Idea if (!color) { @@ -441,12 +491,13 @@ color = command != null && command.contains("idea"); } if (!color) { - color = tbs.isConsoleOutput() && System.getenv("TERM") != null; + color = system.get(TerminalProvider.Stream.Output) && System.getenv("TERM") != null; } if (!color && dumb == null) { if (Log.isDebugEnabled()) { - Log.warn("input is tty: {}", tbs.isConsoleInput()); - Log.warn("output is tty: {}", tbs.isConsoleOutput()); + Log.warn("input is tty: {}", system.get(TerminalProvider.Stream.Input)); + Log.warn("output is tty: {}", system.get(TerminalProvider.Stream.Output)); + Log.warn("error is tty: {}", system.get(TerminalProvider.Stream.Error)); Log.warn("Creating a dumb terminal", exception); } else { Log.warn("Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)"); @@ -454,33 +505,49 @@ } } terminal = new DumbTerminal(name, color ? Terminal.TYPE_DUMB_COLOR : Terminal.TYPE_DUMB, - inputStreamWrapper.apply(new FileInputStream(FileDescriptor.in)), - new FileOutputStream(FileDescriptor.out), + new FileInputStream(FileDescriptor.in), + new FileOutputStream(console == TerminalProvider.Stream.Output ? FileDescriptor.out : FileDescriptor.err), encoding, signalHandler); } - if (terminal == null) { - throw exception; - } - return terminal; } else { - if (jna) { - try { - Pty pty = load(JnaSupport.class).open(attributes, size); - return new PosixPtyTerminal(name, type, pty, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused); - } catch (Throwable t) { - Log.debug("Error creating JNA based terminal: ", t.getMessage(), t); + for ( TerminalProvider provider : providers) { + if (terminal == null) { + try { + terminal = provider.newTerminal(name, type, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused, attributes, size); + } catch (Throwable t) { + Log.debug("Error creating " + provider.name() + " based terminal: ", t.getMessage(), t); + exception.addSuppressed(t); + } } } - if (jansi) { - try { - Pty pty = load(JansiSupport.class).open(attributes, size); - return new PosixPtyTerminal(name, type, pty, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused); - } catch (Throwable t) { - Log.debug("Error creating JANSI based terminal: ", t.getMessage(), t); - } + } + if (terminal == null) { + throw exception; + } + return terminal; + } + + private TerminalProvider.Stream select(Map system, SystemOutput systemOutput) { + switch (systemOutput) { + case SysOut: + return select(system, TerminalProvider.Stream.Output); + case SysErr: + return select(system, TerminalProvider.Stream.Error); + case SysOutOrSysErr: + return select(system, TerminalProvider.Stream.Output, TerminalProvider.Stream.Error); + case SysErrOrSysOut: + return select(system, TerminalProvider.Stream.Error, TerminalProvider.Stream.Output); + } + return null; + } + + private static TerminalProvider.Stream select(Map system, TerminalProvider.Stream... streams) { + for (TerminalProvider.Stream s : streams) { + if (system.get(s)) { + return s; } - return new ExternalTerminal(name, type, inputStreamWrapper.apply(in), out, encoding, signalHandler, paused, attributes, size); } + return null; } private static String getParentProcessCommand() { @@ -512,6 +579,24 @@ return ServiceLoader.load(clazz, clazz.getClassLoader()).iterator().next(); } + private static final int UTF8_CODE_PAGE = 65001; + + private static Charset getCodepageCharset(int codepage) { + //http://docs.oracle.com/javase/6/docs/technotes/guides/intl/encoding.doc.html + if (codepage == UTF8_CODE_PAGE) { + return StandardCharsets.UTF_8; + } + String charsetMS = "ms" + codepage; + if (Charset.isSupported(charsetMS)) { + return Charset.forName(charsetMS); + } + String charsetCP = "cp" + codepage; + if (Charset.isSupported(charsetCP)) { + return Charset.forName(charsetCP); + } + return Charset.defaultCharset(); + } + /** * Allows an application to override the result of {@link #build()}. The * intended use case is to allow a container or server application to control @@ -545,79 +630,4 @@ TERMINAL_OVERRIDE.set(terminal); } - private static class TerminalBuilderSupport { - private JansiSupport jansiSupport = null; - private JnaSupport jnaSupport = null; - private Pty pty = null; - private boolean consoleOutput; - - TerminalBuilderSupport(boolean jna, boolean jansi) { - if (jna) { - try { - jnaSupport = load(JnaSupport.class); - consoleOutput = jnaSupport.isConsoleOutput(); - } catch (Throwable e) { - jnaSupport = null; - Log.debug("jnaSupport.isConsoleOutput(): ", e); - } - } - if (jansi) { - try { - jansiSupport = load(JansiSupport.class); - consoleOutput = jansiSupport.isConsoleOutput(); - } catch (Throwable e) { - jansiSupport = null; - Log.debug("jansiSupport.isConsoleOutput(): ", e); - } - } - if (jnaSupport == null && jansiSupport == null) { - try { - pty = ExecPty.current(); - consoleOutput = true; - } catch (Exception e) { - Log.debug("ExecPty.current(): ", e); - } - } - } - - public boolean isConsoleOutput() { - return consoleOutput; - } - - public boolean isConsoleInput() { - if (pty != null) { - return true; - } else if (hasJnaSupport()) { - return jnaSupport.isConsoleInput(); - } else if (hasJansiSupport()) { - return jansiSupport.isConsoleInput(); - } else { - return false; - } - } - - public boolean hasJnaSupport() { - return jnaSupport != null; - } - - public boolean hasJansiSupport() { - return jansiSupport != null; - } - - public JnaSupport getJnaSupport() { - return jnaSupport; - } - - public JansiSupport getJansiSupport() { - return jansiSupport; - } - - public Pty getExecPty() throws IOException { - if (pty == null) { - pty = ExecPty.current(); - } - return pty; - } - - } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Colors.java 2023-10-06 05:33:33.000000000 +0000 @@ -534,7 +534,7 @@ H = 0; return H; } else { - throw new IllegalArgumentException("h outside assumed range 0..360: " + Double.toString(h)); + throw new IllegalArgumentException("h outside assumed range 0..360: " + h); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Curses.java 2023-10-06 05:33:33.000000000 +0000 @@ -12,7 +12,7 @@ import java.io.IOError; import java.io.IOException; import java.io.StringWriter; -import java.util.Stack; +import java.util.ArrayDeque; /** * Curses helper methods. @@ -21,8 +21,8 @@ */ public final class Curses { - private static Object[] sv = new Object[26]; - private static Object[] dv = new Object[26]; + private static final Object[] sv = new Object[26]; + private static final Object[] dv = new Object[26]; private static final int IFTE_NONE = 0; private static final int IFTE_IF = 1; @@ -68,7 +68,7 @@ int length = str.length(); int ifte = IFTE_NONE; boolean exec = true; - Stack stack = new Stack<>(); + ArrayDeque stack = new ArrayDeque<>(); while (index < length) { char ch = str.charAt(index++); switch (ch) { @@ -197,7 +197,7 @@ int start = index; while (str.charAt(index++) != '}') ; if (exec) { - int v = Integer.valueOf(str.substring(start, index - 1)); + int v = Integer.parseInt(str.substring(start, index - 1)); stack.push(v); } break; @@ -470,7 +470,7 @@ } else if (pop instanceof Boolean) { return (Boolean) pop ? 1 : 0; } else { - return Integer.valueOf(pop.toString()); + return Integer.parseInt(pop.toString()); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Display.java 2023-10-06 05:33:33.000000000 +0000 @@ -187,7 +187,7 @@ int lineIndex = 0; int currentPos = 0; - int numLines = Math.max(oldLines.size(), newLines.size()); + int numLines = Math.min(rows, Math.max(oldLines.size(), newLines.size())); boolean wrapNeeded = false; while (lineIndex < numLines) { AttributedString oldLine = diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/InfoCmp.java 2023-10-06 05:33:33.000000000 +0000 @@ -503,7 +503,7 @@ public String[] getNames() { return getCapabilitiesByName().entrySet().stream() .filter(e -> e.getValue() == this) - .map(Map.Entry::getValue) + .map(Map.Entry::getKey) .toArray(String[]::new); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStreamImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -123,20 +123,17 @@ notifyAll(); } - boolean isInfinite = (timeout <= 0L); - /* * So the thread is currently doing the reading for us. So * now we play the waiting game. */ - while (isInfinite || timeout > 0L) { - long start = System.currentTimeMillis (); - + Timeout t = new Timeout(timeout); + while (!t.elapsed()) { try { if (Thread.interrupted()) { throw new InterruptedException(); } - wait(timeout); + wait(t.timeout()); } catch (InterruptedException e) { exception = (IOException) new InterruptedIOException().initCause(e); @@ -155,10 +152,6 @@ assert exception == null; break; } - - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingInputStream.java 2023-10-06 05:33:33.000000000 +0000 @@ -79,12 +79,34 @@ } public int readBuffered(byte[] b) throws IOException { + return readBuffered(b, 0L); + } + + public int readBuffered(byte[] b, long timeout) throws IOException { + return readBuffered(b, 0, b.length, timeout); + } + + public int readBuffered(byte[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; } else { - return super.read(b, 0, b.length); + Timeout t = new Timeout(timeout); + int nb = 0; + while (!t.elapsed()) { + int r = read(nb > 0 ? 1 : t.timeout()); + if (r < 0) { + return nb > 0 ? nb : r; + } + b[off + nb++] = (byte) r; + if (nb >= len || t.isInfinite()) { + break; + } + } + return nb; } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlocking.java 2023-10-06 05:33:33.000000000 +0000 @@ -95,13 +95,9 @@ @Override public int read(long timeout, boolean isPeek) throws IOException { - boolean isInfinite = (timeout <= 0L); - while (!bytes.hasRemaining() && (isInfinite || timeout > 0L)) { - long start = 0; - if (!isInfinite) { - start = System.currentTimeMillis(); - } - int c = reader.read(timeout); + Timeout t = new Timeout(timeout); + while (!bytes.hasRemaining() && !t.elapsed()) { + int c = reader.read(t.timeout()); if (c == EOF) { return EOF; } @@ -117,9 +113,6 @@ encoder.encode(chars, bytes, false); bytes.flip(); } - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } if (bytes.hasRemaining()) { if (isPeek) { @@ -151,21 +144,17 @@ public NonBlockingInputStreamReader(NonBlockingInputStream input, CharsetDecoder decoder) { this.input = input; this.decoder = decoder; - this.bytes = ByteBuffer.allocate(4); - this.chars = CharBuffer.allocate(2); + this.bytes = ByteBuffer.allocate(2048); + this.chars = CharBuffer.allocate(1024); this.bytes.limit(0); this.chars.limit(0); } @Override protected int read(long timeout, boolean isPeek) throws IOException { - boolean isInfinite = (timeout <= 0L); - while (!chars.hasRemaining() && (isInfinite || timeout > 0L)) { - long start = 0; - if (!isInfinite) { - start = System.currentTimeMillis(); - } - int b = input.read(timeout); + Timeout t = new Timeout(timeout); + while (!chars.hasRemaining() && !t.elapsed()) { + int b = input.read(t.timeout()); if (b == EOF) { return EOF; } @@ -181,10 +170,6 @@ decoder.decode(bytes, chars, false); chars.flip(); } - - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } if (chars.hasRemaining()) { if (isPeek) { @@ -198,46 +183,37 @@ } @Override - public int readBuffered(char[] b) throws IOException { + public int readBuffered(char[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; + } else if (chars.hasRemaining()) { + int r = Math.min(len, chars.remaining()); + chars.get(b, off, r); + return r; } else { - if (chars.hasRemaining()) { - int r = Math.min(b.length, chars.remaining()); - chars.get(b); - return r; - } else { - byte[] buf = new byte[b.length]; - int l = input.readBuffered(buf); - if (l < 0) { - return l; - } else { - ByteBuffer currentBytes; - if (bytes.hasRemaining()) { - int transfer = bytes.remaining(); - byte[] newBuf = new byte[l + transfer]; - bytes.get(newBuf, 0, transfer); - System.arraycopy(buf, 0, newBuf, transfer, l); - currentBytes = ByteBuffer.wrap(newBuf); - bytes.position(0); - bytes.limit(0); - } else { - currentBytes = ByteBuffer.wrap(buf, 0, l); - } - CharBuffer chars = CharBuffer.wrap(b); - decoder.decode(currentBytes, chars, false); - chars.flip(); - if (currentBytes.hasRemaining()) { - int pos = bytes.position(); - bytes.limit(bytes.limit() + currentBytes.remaining()); - bytes.put(currentBytes); - bytes.position(pos); - } - return chars.remaining(); + Timeout t = new Timeout(timeout); + while (!chars.hasRemaining() && !t.elapsed()) { + if (!bytes.hasRemaining()) { + bytes.position(0); + bytes.limit(0); + } + int nb = input.readBuffered(bytes.array(), bytes.limit(), + bytes.capacity() - bytes.limit(), t.timeout()); + if (nb < 0) { + return nb; } + bytes.limit(bytes.limit() + nb); + chars.clear(); + decoder.decode(bytes, chars, false); + chars.flip(); } + int nb = Math.min(len, chars.remaining()); + chars.get(b, off, nb); + return nb; } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpInputStream.java 2023-10-06 05:33:33.000000000 +0000 @@ -45,24 +45,17 @@ } private int wait(ByteBuffer buffer, long timeout) throws IOException { - boolean isInfinite = (timeout <= 0L); - long end = 0; - if (!isInfinite) { - end = System.currentTimeMillis() + timeout; - } - while (!closed && !buffer.hasRemaining() && (isInfinite || timeout > 0L)) { + Timeout t = new Timeout(timeout); + while (!closed && !buffer.hasRemaining() && !t.elapsed()) { // Wake up waiting readers/writers notifyAll(); try { - wait(timeout); + wait(t.timeout()); checkIoException(); } catch (InterruptedException e) { checkIoException(); throw new InterruptedIOException(); } - if (!isInfinite) { - timeout = end - System.currentTimeMillis(); - } } return buffer.hasRemaining() ? 0 @@ -107,17 +100,25 @@ } @Override - public synchronized int readBuffered(byte[] b) throws IOException { - checkIoException(); - int res = wait(readBuffer, 0L); - if (res >= 0) { - res = 0; - while (res < b.length && readBuffer.hasRemaining()) { - b[res++] = (byte) (readBuffer.get() & 0x00FF); + public synchronized int readBuffered(byte[] b, int off, int len, long timeout) throws IOException { + if (b == null) { + throw new NullPointerException(); + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { + return 0; + } else { + checkIoException(); + int res = wait(readBuffer, timeout); + if (res >= 0) { + res = 0; + while (res < len && readBuffer.hasRemaining()) { + b[off + res++] = (byte) (readBuffer.get() & 0x00FF); + } } + rewind(readBuffer, writeBuffer); + return res; } - rewind(readBuffer, writeBuffer); - return res; } public synchronized void setIoException(IOException exception) { diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingPumpReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -106,10 +106,12 @@ } @Override - public int readBuffered(char[] b) throws IOException { + public int readBuffered(char[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; } else { final ReentrantLock lock = this.lock; @@ -117,7 +119,13 @@ try { if (!closed && count == 0) { try { - notEmpty.await(); + if (timeout > 0) { + if (!notEmpty.await(timeout, TimeUnit.MILLISECONDS)) { + throw new IOException( "Timeout reading" ); + } + } else { + notEmpty.await(); + } } catch (InterruptedException e) { throw (IOException) new InterruptedIOException().initCause(e); } @@ -127,9 +135,9 @@ } else if (count == 0) { return READ_EXPIRED; } else { - int r = Math.min(b.length, count); + int r = Math.min(len, count); for (int i = 0; i < r; i++) { - b[i] = buffer[read++]; + b[off + i] = buffer[read++]; if (read == buffer.length) { read = 0; } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReaderImpl.java 2023-10-06 05:33:33.000000000 +0000 @@ -91,10 +91,12 @@ } @Override - public int readBuffered(char[] b) throws IOException { + public int readBuffered(char[] b, int off, int len, long timeout) throws IOException { if (b == null) { throw new NullPointerException(); - } else if (b.length == 0) { + } else if (off < 0 || len < 0 || off + len < b.length) { + throw new IllegalArgumentException(); + } else if (len == 0) { return 0; } else if (exception != null) { assert ch == READ_EXPIRED; @@ -105,15 +107,16 @@ b[0] = (char) ch; ch = READ_EXPIRED; return 1; - } else if (!threadIsReading) { - return in.read(b); + } else if (!threadIsReading && timeout <= 0) { + return in.read(b, off, len); } else { - int c = read(-1, false); + // TODO: rework implementation to read as much as possible + int c = read(timeout, false); if (c >= 0) { - b[0] = (char) c; + b[off] = (char) c; return 1; } else { - return -1; + return c; } } } @@ -158,20 +161,17 @@ notifyAll(); } - boolean isInfinite = (timeout <= 0L); - /* * So the thread is currently doing the reading for us. So * now we play the waiting game. */ - while (isInfinite || timeout > 0L) { - long start = System.currentTimeMillis (); - + Timeout t = new Timeout(timeout); + while (!t.elapsed()) { try { if (Thread.interrupted()) { throw new InterruptedException(); } - wait(timeout); + wait(t.timeout()); } catch (InterruptedException e) { exception = (IOException) new InterruptedIOException().initCause(e); @@ -190,10 +190,6 @@ assert exception == null; break; } - - if (!isInfinite) { - timeout -= System.currentTimeMillis() - start; - } } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/NonBlockingReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -85,7 +85,15 @@ return 1; } - public abstract int readBuffered(char[] b) throws IOException; + public int readBuffered(char[] b) throws IOException { + return readBuffered(b, 0L); + } + + public int readBuffered(char[] b, long timeout) throws IOException { + return readBuffered(b, 0, b.length, timeout); + } + + public abstract int readBuffered(char[] b, int off, int len, long timeout) throws IOException; public int available() { return 0; diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java 2023-10-06 05:33:33.000000000 +0000 @@ -9,6 +9,8 @@ package jdk.internal.org.jline.utils; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; public class OSUtils { @@ -28,6 +30,12 @@ && (System.getenv("MSYSTEM").startsWith("MINGW") || System.getenv("MSYSTEM").equals("MSYS")); + public static final boolean IS_WSL = System.getenv("WSL_DISTRO_NAME") != null; + + public static final boolean IS_WSL1 = IS_WSL && System.getenv("WSL_INTEROP") == null; + + public static final boolean IS_WSL2 = IS_WSL && !IS_WSL1; + public static final boolean IS_CONEMU = IS_WINDOWS && System.getenv("ConEmuPID") != null; @@ -38,17 +46,20 @@ public static String STTY_COMMAND; public static String STTY_F_OPTION; public static String INFOCMP_COMMAND; + public static String TEST_COMMAND; static { String tty; String stty; String sttyfopt; String infocmp; + String test; if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) { - tty = "tty.exe"; - stty = "stty.exe"; + tty = null; + stty = null; sttyfopt = null; - infocmp = "infocmp.exe"; + infocmp = null; + test = null; String path = System.getenv("PATH"); if (path != null) { String[] paths = path.split(";"); @@ -62,23 +73,39 @@ if (infocmp == null && new File(p, "infocmp.exe").exists()) { infocmp = new File(p, "infocmp.exe").getAbsolutePath(); } + if (test == null && new File(p, "test.exe").exists()) { + test = new File(p, "test.exe").getAbsolutePath(); + } } } + if (tty == null) { + tty = "tty.exe"; + } + if (stty == null) { + stty = "stty.exe"; + } + if (infocmp == null) { + infocmp = "infocmp.exe"; + } + if (test == null) { + test = "test.exe"; + } } else { tty = "tty"; - stty = "stty"; + stty = IS_OSX ? "/bin/stty" : "stty"; + sttyfopt = IS_OSX ? "-f" : "-F"; infocmp = "infocmp"; - if (IS_OSX) { - sttyfopt = "-f"; - } - else { - sttyfopt = "-F"; - } + test = isTestCommandValid("/usr/bin/test") ? "/usr/bin/test" + : "/bin/test"; } TTY_COMMAND = tty; STTY_COMMAND = stty; STTY_F_OPTION = sttyfopt; INFOCMP_COMMAND = infocmp; + TEST_COMMAND = test; } + private static boolean isTestCommandValid(String command) { + return Files.isExecutable(Paths.get(command)); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/PumpReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -36,7 +36,7 @@ } public PumpReader(int bufferSize) { - char[] buf = new char[bufferSize]; + char[] buf = new char[Math.max(bufferSize, 2)]; this.readBuffer = CharBuffer.wrap(buf); this.writeBuffer = CharBuffer.wrap(buf); this.writer = new Writer(this); @@ -53,13 +53,27 @@ return new InputStream(this, charset); } - private boolean wait(CharBuffer buffer) throws InterruptedIOException { - if (closed) { - return false; + /** + * Blocks until more input is available, even if {@link #readBuffer} already + * contains some chars; or until the reader is closed. + * + * @return true if more input is available, false if no additional input is + * available and the reader is closed + * @throws InterruptedIOException If {@link #wait()} is interrupted + */ + private boolean waitForMoreInput() throws InterruptedIOException { + if (!writeBuffer.hasRemaining()) { + throw new AssertionError("No space in write buffer"); } - while (!buffer.hasRemaining()) { - // Wake up waiting readers/writers + int oldRemaining = readBuffer.remaining(); + + do { + if (closed) { + return false; + } + + // Wake up waiting writers notifyAll(); try { @@ -67,19 +81,41 @@ } catch (InterruptedException e) { throw new InterruptedIOException(); } + } while (readBuffer.remaining() <= oldRemaining); + + return true; + } + /** + * Waits until {@code buffer.hasRemaining() == true}, or it is false and + * the reader is {@link #closed}. + * + * @return true if {@code buffer.hasRemaining() == true}; false otherwise + * when reader is closed + */ + private boolean wait(CharBuffer buffer) throws InterruptedIOException { + while (!buffer.hasRemaining()) { if (closed) { return false; } + + // Wake up waiting readers/writers + notifyAll(); + + try { + wait(); + } catch (InterruptedException e) { + throw new InterruptedIOException(); + } } return true; } /** - * Blocks until more input is available or the reader is closed. + * Blocks until input is available or the reader is closed. * - * @return true if more input is available, false if the reader is closed + * @return true if input is available, false if no input is available and the reader is closed * @throws InterruptedIOException If {@link #wait()} is interrupted */ private boolean waitForInput() throws InterruptedIOException { @@ -94,7 +130,8 @@ * @throws ClosedException If the reader was closed */ private void waitForBufferSpace() throws InterruptedIOException, ClosedException { - if (!wait(writeBuffer)) { + // Check `closed` to throw even if writer buffer has space available + if (!wait(writeBuffer) || closed) { throw new ClosedException(); } } @@ -122,7 +159,9 @@ * @return If more input is available */ private boolean rewindReadBuffer() { - return rewind(readBuffer, writeBuffer) && readBuffer.hasRemaining(); + boolean rw = rewind(readBuffer, writeBuffer) && readBuffer.hasRemaining(); + notifyAll(); + return rw; } /** @@ -131,6 +170,7 @@ */ private void rewindWriteBuffer() { rewind(writeBuffer, readBuffer); + notifyAll(); } @Override @@ -202,10 +242,33 @@ } private void encodeBytes(CharsetEncoder encoder, ByteBuffer output) throws IOException { + int oldPos = output.position(); CoderResult result = encoder.encode(readBuffer, output, false); - if (rewindReadBuffer() && result.isUnderflow()) { - encoder.encode(readBuffer, output, false); + int encodedCount = output.position() - oldPos; + + if (result.isUnderflow()) { + boolean hasMoreInput = rewindReadBuffer(); + boolean reachedEndOfInput = false; + + // If encoding did not make any progress must block for more input + if (encodedCount == 0 && !hasMoreInput) { + reachedEndOfInput = !waitForMoreInput(); + } + + result = encoder.encode(readBuffer, output, reachedEndOfInput); + if (result.isError()) { + result.throwException(); + } + if (!reachedEndOfInput && output.position() - oldPos == 0) { + throw new AssertionError("Failed to encode any chars"); + } rewindReadBuffer(); + } else if (result.isOverflow()) { + if (encodedCount == 0) { + throw new AssertionError("Output buffer has not enough space"); + } + } else { + result.throwException(); } } @@ -334,7 +397,7 @@ this.encoder = charset.newEncoder() .onUnmappableCharacter(CodingErrorAction.REPLACE) .onMalformedInput(CodingErrorAction.REPLACE); - this.buffer = ByteBuffer.allocate((int) Math.ceil(encoder.maxBytesPerChar())); + this.buffer = ByteBuffer.allocate((int) Math.ceil(encoder.maxBytesPerChar() * 2)); // No input available after initialization buffer.limit(0); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/StyleResolver.java 2023-10-06 05:33:33.000000000 +0000 @@ -241,7 +241,7 @@ if (spec.length() == 1) { // log.warning("Invalid style-reference; missing discriminator: " + spec); } else { - String name = spec.substring(1, spec.length()); + String name = spec.substring(1); String resolvedSpec = source.apply(name); if (resolvedSpec != null) { return apply(style, resolvedSpec); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/Timeout.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002-2018, the original author or authors. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + * + * https://opensource.org/licenses/BSD-3-Clause + */ +package jdk.internal.org.jline.utils; + +/** + * Helper class ti use during I/O operations with an eventual timeout. + */ +public class Timeout { + + private final long timeout; + private long cur = 0; + private long end = Long.MAX_VALUE; + + public Timeout(long timeout) { + this.timeout = timeout; + } + + public boolean isInfinite() { + return timeout <= 0; + } + + public boolean isFinite() { + return timeout > 0; + } + + public boolean elapsed() { + if (timeout > 0) { + cur = System.currentTimeMillis(); + if (end == Long.MAX_VALUE) { + end = cur + timeout; + } + return cur >= end; + } else { + return false; + } + } + + public long timeout() { + return timeout > 0 ? Math.max(1, end - cur) : timeout; + } + +} diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/WCWidth.java 2023-10-06 05:33:33.000000000 +0000 @@ -70,6 +70,7 @@ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */ (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */ (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x1f000 && ucs <= 0x1feee) || (ucs >= 0x20000 && ucs <= 0x2fffd) || (ucs >= 0x30000 && ucs <= 0x3fffd))) ? 1 : 0); } @@ -123,8 +124,8 @@ new Interval( 0x10A01, 0x10A03 ), new Interval( 0x10A05, 0x10A06 ), new Interval( 0x10A0C, 0x10A0F ), new Interval( 0x10A38, 0x10A3A ), new Interval( 0x10A3F, 0x10A3F ), new Interval( 0x1D167, 0x1D169 ), new Interval( 0x1D173, 0x1D182 ), new Interval( 0x1D185, 0x1D18B ), new Interval( 0x1D1AA, 0x1D1AD ), - new Interval( 0x1D242, 0x1D244 ), new Interval( 0xE0001, 0xE0001 ), new Interval( 0xE0020, 0xE007F ), - new Interval( 0xE0100, 0xE01EF ) + new Interval( 0x1D242, 0x1D244 ), new Interval( 0x1F3FB, 0x1F3FF ), new Interval( 0xE0001, 0xE0001 ), + new Interval( 0xE0020, 0xE007F ), new Interval( 0xE0100, 0xE01EF ) }; private static class Interval { diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/windows-vtp.caps 2023-10-06 05:33:33.000000000 +0000 @@ -2,7 +2,7 @@ am, mc5i, mir, msgr, colors#256, cols#80, it#8, lines#24, ncv#3, pairs#64, bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, clear=\E[H\E[J, - cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\E[B, + cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A, il=\E[%p1%dL, il1=\E[L, diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/module-info.java openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/module-info.java --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/classes/module-info.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/classes/module-info.java 2023-10-06 05:33:33.000000000 +0000 @@ -56,8 +56,5 @@ exports jdk.internal.org.jline.terminal.spi to jdk.scripting.nashorn.shell, jdk.jshell; - - uses jdk.internal.org.jline.terminal.spi.JnaSupport; - } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/legal/jline.md openjdk-lts-11.0.21+9/src/jdk.internal.le/share/legal/jline.md --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/share/legal/jline.md 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/share/legal/jline.md 2023-10-06 05:33:33.000000000 +0000 @@ -1,4 +1,4 @@ -## JLine v3.20.0 +## JLine v3.22.0 ### JLine License
    @@ -41,10 +41,10 @@
     
     4th Party Dependency
     =============
    -org.fusesource.jansi version 1.17.1
    -org.apache.sshd 2.1 to 3
    -org.apache.felix.gogo.runtime 1.1.2
    -org.apache.felix.gogo.jline 1.1.4
    +org.fusesource.jansi version 2.4.0
    +org.apache.sshd 2.9.2
    +org.apache.felix.gogo.runtime 1.1.6
    +org.apache.felix.gogo.jline 1.1.8
     =============
     Apache License
                               Version 2.0, January 2004
    @@ -262,7 +262,7 @@
     SLF4J source code and binaries are distributed under the MIT license.
     
     
    -Copyright (c) 2004-2017 QOS.ch
    +Copyright (c) 2004-2023 QOS.ch
     All rights reserved.
     
     Permission is hereby granted, free of charge, to any person obtaining
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaSupportImpl.java	1970-01-01 00:00:00.000000000 +0000
    @@ -1,77 +0,0 @@
    -/*
    - * Copyright (c) 2002-2019, the original author or authors.
    - *
    - * This software is distributable under the BSD license. See the terms of the
    - * BSD license in the documentation provided with this software.
    - *
    - * https://opensource.org/licenses/BSD-3-Clause
    - */
    -package jdk.internal.org.jline.terminal.impl.jna;
    -
    -import jdk.internal.org.jline.terminal.Attributes;
    -import jdk.internal.org.jline.terminal.Size;
    -import jdk.internal.org.jline.terminal.Terminal;
    -import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal;
    -import jdk.internal.org.jline.terminal.spi.JnaSupport;
    -import jdk.internal.org.jline.terminal.spi.Pty;
    -import jdk.internal.org.jline.utils.OSUtils;
    -
    -import java.io.IOException;
    -import java.io.InputStream;
    -import java.nio.charset.Charset;
    -import java.util.function.Function;
    -
    -public class JnaSupportImpl implements JnaSupport {
    -    @Override
    -    public Pty current() throws IOException {
    -//        return JnaNativePty.current();
    -        throw new UnsupportedOperationException();
    -    }
    -
    -    @Override
    -    public Pty open(Attributes attributes, Size size) throws IOException {
    -//        return JnaNativePty.open(attributes, size);
    -        throw new UnsupportedOperationException();
    -    }
    -
    -    @Override
    -    public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler) throws IOException {
    -        return winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, false);
    -    }
    -
    -    @Override
    -    public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused) throws IOException {
    -        return winSysTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused, input -> input);
    -    }
    -
    -    @Override
    -    public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused, Function inputStreamWrapper) throws IOException {
    -        return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, codepage, nativeSignals, signalHandler, paused, inputStreamWrapper);
    -    }
    -
    -    @Override
    -    public boolean isWindowsConsole() {
    -        return JnaWinSysTerminal.isWindowsConsole();
    -    }
    -
    -    @Override
    -    public boolean isConsoleOutput() {
    -        if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) {
    -            throw new UnsupportedOperationException();
    -        } else if (OSUtils.IS_WINDOWS) {
    -            return JnaWinSysTerminal.isConsoleOutput();
    -        }
    -        throw new UnsupportedOperationException();
    -    }
    -
    -    @Override
    -    public boolean isConsoleInput() {
    -        if (OSUtils.IS_CYGWIN || OSUtils.IS_MSYSTEM) {
    -            throw new UnsupportedOperationException();
    -        } else if (OSUtils.IS_WINDOWS) {
    -            return JnaWinSysTerminal.isConsoleInput();
    -        }
    -        throw new UnsupportedOperationException();
    -    }
    -
    -}
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java	1970-01-01 00:00:00.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/JnaTerminalProvider.java	2023-10-06 05:33:33.000000000 +0000
    @@ -0,0 +1,106 @@
    +/*
    + * Copyright (c) 2002-2020, the original author or authors.
    + *
    + * This software is distributable under the BSD license. See the terms of the
    + * BSD license in the documentation provided with this software.
    + *
    + * https://opensource.org/licenses/BSD-3-Clause
    + */
    +package jdk.internal.org.jline.terminal.impl.jna;
    +
    +import jdk.internal.org.jline.terminal.Attributes;
    +import jdk.internal.org.jline.terminal.Size;
    +import jdk.internal.org.jline.terminal.Terminal;
    +import jdk.internal.org.jline.terminal.impl.PosixPtyTerminal;
    +import jdk.internal.org.jline.terminal.impl.PosixSysTerminal;
    +import jdk.internal.org.jline.terminal.impl.jna.win.JnaWinSysTerminal;
    +import jdk.internal.org.jline.terminal.spi.TerminalProvider;
    +import jdk.internal.org.jline.terminal.spi.Pty;
    +import jdk.internal.org.jline.utils.OSUtils;
    +
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.io.OutputStream;
    +import java.nio.charset.Charset;
    +import java.util.function.Function;
    +
    +public class JnaTerminalProvider implements TerminalProvider
    +{
    +    @Override
    +    public String name() {
    +        return "jna";
    +    }
    +
    +//    public Pty current(TerminalProvider.Stream console) throws IOException {
    +//        return JnaNativePty.current(console);
    +//    }
    +//
    +//    public Pty open(Attributes attributes, Size size) throws IOException {
    +//        return JnaNativePty.open(attributes, size);
    +//    }
    +
    +    @Override
    +    public Terminal sysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
    +                                boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
    +                                Stream consoleStream, Function inputStreamWrapper) throws IOException {
    +        if (OSUtils.IS_WINDOWS) {
    +            return winSysTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream, inputStreamWrapper );
    +        } else {
    +            return null;
    +        }
    +    }
    +
    +    public Terminal winSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
    +                                   boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
    +                                   Stream console, Function inputStreamWrapper) throws IOException {
    +        return JnaWinSysTerminal.createTerminal(name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, console, inputStreamWrapper);
    +    }
    +
    +//    public Terminal posixSysTerminal(String name, String type, boolean ansiPassThrough, Charset encoding,
    +//                                     boolean nativeSignals, Terminal.SignalHandler signalHandler, boolean paused,
    +//                                     Stream consoleStream) throws IOException {
    +//        Pty pty = current(consoleStream);
    +//        return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler);
    +//    }
    +
    +    @Override
    +    public Terminal newTerminal(String name, String type, InputStream in, OutputStream out,
    +                                Charset encoding, Terminal.SignalHandler signalHandler, boolean paused,
    +                                Attributes attributes, Size size) throws IOException
    +    {
    +//        Pty pty = open(attributes, size);
    +//        return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
    +        return null;
    +    }
    +
    +    @Override
    +    public boolean isSystemStream(Stream stream) {
    +        try {
    +            if (OSUtils.IS_WINDOWS) {
    +                return isWindowsSystemStream(stream);
    +            } else {
    +//                return isPosixSystemStream(stream);
    +                return false;
    +            }
    +        } catch (Throwable t) {
    +            return false;
    +        }
    +    }
    +
    +    public boolean isWindowsSystemStream(Stream stream) {
    +        return JnaWinSysTerminal.isWindowsSystemStream(stream);
    +    }
    +
    +//    public boolean isPosixSystemStream(Stream stream) {
    +//        return JnaNativePty.isPosixSystemStream(stream);
    +//    }
    +
    +    @Override
    +    public String systemStreamName(Stream stream) {
    +//        if (OSUtils.IS_WINDOWS) {
    +            return null;
    +//        } else {
    +//            return JnaNativePty.posixSystemStreamName(stream);
    +//        }
    +    }
    +}
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinConsoleWriter.java	2023-10-06 05:33:33.000000000 +0000
    @@ -17,17 +17,17 @@
     
     class JnaWinConsoleWriter extends AbstractWindowsConsoleWriter {
     
    -    private final Pointer consoleHandle;
    +    private final Pointer console;
         private final IntByReference writtenChars = new IntByReference();
     
    -    JnaWinConsoleWriter(Pointer consoleHandle) {
    -        this.consoleHandle = consoleHandle;
    +    JnaWinConsoleWriter(Pointer console) {
    +        this.console = console;
         }
     
         @Override
         protected void writeConsole(char[] text, int len) throws IOException {
             try {
    -            Kernel32.INSTANCE.WriteConsoleW(this.consoleHandle, text, len, this.writtenChars, null);
    +            Kernel32.INSTANCE.WriteConsoleW(this.console, text, len, this.writtenChars, null);
             } catch (LastErrorException e) {
                 throw new IOException("Failed to write to console", e);
             }
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/jdk/internal/org/jline/terminal/impl/jna/win/JnaWinSysTerminal.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2002-2019, the original author or authors.
    + * Copyright (c) 2002-2020, the original author or authors.
      *
      * This software is distributable under the BSD license. See the terms of the
      * BSD license in the documentation provided with this software.
    @@ -19,11 +19,10 @@
     //import com.sun.jna.LastErrorException;
     //import com.sun.jna.Pointer;
     //import com.sun.jna.ptr.IntByReference;
    -
     import jdk.internal.org.jline.terminal.Cursor;
     import jdk.internal.org.jline.terminal.Size;
    -import jdk.internal.org.jline.terminal.Terminal;
     import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal;
    +import jdk.internal.org.jline.terminal.spi.TerminalProvider;
     import jdk.internal.org.jline.utils.InfoCmp;
     import jdk.internal.org.jline.utils.OSUtils;
     
    @@ -31,38 +30,50 @@
     
         private static final Pointer consoleIn = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_INPUT_HANDLE);
         private static final Pointer consoleOut = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_OUTPUT_HANDLE);
    +    private static final Pointer consoleErr = Kernel32.INSTANCE.GetStdHandle(Kernel32.STD_ERROR_HANDLE);
     
    -    public static JnaWinSysTerminal createTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, boolean paused, Function inputStreamWrapper) throws IOException {
    +    public static JnaWinSysTerminal createTerminal(String name, String type, boolean ansiPassThrough, Charset encoding, boolean nativeSignals, SignalHandler signalHandler, boolean paused, TerminalProvider.Stream consoleStream, Function inputStreamWrapper) throws IOException {
    +        Pointer console;
    +        switch (consoleStream) {
    +            case Output:
    +                console = JnaWinSysTerminal.consoleOut;
    +                break;
    +            case Error:
    +                console = JnaWinSysTerminal.consoleErr;
    +                break;
    +            default:
    +                throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream);
    +        }
             Writer writer;
             if (ansiPassThrough) {
                 if (type == null) {
                     type = OSUtils.IS_CONEMU ? TYPE_WINDOWS_CONEMU : TYPE_WINDOWS;
                 }
    -            writer = new JnaWinConsoleWriter(consoleOut);
    +            writer = new JnaWinConsoleWriter(console);
             } else {
                 IntByReference mode = new IntByReference();
    -            Kernel32.INSTANCE.GetConsoleMode(consoleOut, mode);
    +            Kernel32.INSTANCE.GetConsoleMode(console, mode);
                 try {
    -                Kernel32.INSTANCE.SetConsoleMode(consoleOut, mode.getValue() | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING);
    +                Kernel32.INSTANCE.SetConsoleMode(console, mode.getValue() | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING);
                     if (type == null) {
                         type = TYPE_WINDOWS_VTP;
                     }
    -                writer = new JnaWinConsoleWriter(consoleOut);
    +                writer = new JnaWinConsoleWriter(console);
                 } catch (LastErrorException e) {
                     if (OSUtils.IS_CONEMU) {
                         if (type == null) {
                             type = TYPE_WINDOWS_CONEMU;
                         }
    -                    writer = new JnaWinConsoleWriter(consoleOut);
    +                    writer = new JnaWinConsoleWriter(console);
                     } else {
                         if (type == null) {
                             type = TYPE_WINDOWS;
                         }
    -                    writer = new WindowsAnsiWriter(new BufferedWriter(new JnaWinConsoleWriter(consoleOut)), consoleOut);
    +                    writer = new WindowsAnsiWriter(new BufferedWriter(new JnaWinConsoleWriter(console)), console);
                     }
                 }
             }
    -        JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, codepage, nativeSignals, signalHandler, inputStreamWrapper);
    +        JnaWinSysTerminal terminal = new JnaWinSysTerminal(writer, name, type, encoding, nativeSignals, signalHandler, inputStreamWrapper);
             // Start input pump thread
             if (!paused) {
                 terminal.resume();
    @@ -70,39 +81,26 @@
             return terminal;
         }
     
    -    public static boolean isWindowsConsole() {
    -        try {
    -            IntByReference mode = new IntByReference();
    -            Kernel32.INSTANCE.GetConsoleMode(consoleOut, mode);
    -            Kernel32.INSTANCE.GetConsoleMode(consoleIn, mode);
    -            return true;
    -        } catch (LastErrorException e) {
    -            return false;
    -        }
    -    }
    -
    -    public static boolean isConsoleOutput() {
    +    public static boolean isWindowsSystemStream(TerminalProvider.Stream stream) {
             try {
                 IntByReference mode = new IntByReference();
    -            Kernel32.INSTANCE.GetConsoleMode(consoleOut, mode);
    -            return true;
    -        } catch (LastErrorException e) {
    -            return false;
    -        }
    -    }
    -
    -    public static boolean isConsoleInput() {
    -        try {
    -            IntByReference mode = new IntByReference();
    -            Kernel32.INSTANCE.GetConsoleMode(consoleIn, mode);
    +            Pointer console;
    +            switch (stream) {
    +                case Input: console = consoleIn; break;
    +                case Output: console = consoleOut; break;
    +                case Error: console = consoleErr; break;
    +                default: return false;
    +            }
    +            Kernel32.INSTANCE.GetConsoleMode(console, mode);
                 return true;
             } catch (LastErrorException e) {
                 return false;
             }
         }
     
    -    JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, int codepage, boolean nativeSignals, SignalHandler signalHandler, Function inputStreamWrapper) throws IOException {
    -        super(writer, name, type, encoding, codepage, nativeSignals, signalHandler, inputStreamWrapper);
    +    JnaWinSysTerminal(Writer writer, String name, String type, Charset encoding, boolean nativeSignals, SignalHandler signalHandler,
    +            Function inputStreamWrapper) throws IOException {
    +        super(writer, name, type, encoding, nativeSignals, signalHandler, inputStreamWrapper);
             strings.put(InfoCmp.Capability.key_mouse, "\\E[M");
         }
     
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/module-info.java.extra openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/module-info.java.extra
    --- openjdk-lts-11.0.20.1+1/src/jdk.internal.le/windows/classes/module-info.java.extra	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.internal.le/windows/classes/module-info.java.extra	1970-01-01 00:00:00.000000000 +0000
    @@ -1,27 +0,0 @@
    -/*
    - * Copyright (c) 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.  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.
    - */
    -
    -
    -provides jdk.internal.org.jline.terminal.spi.JnaSupport with jdk.internal.org.jline.terminal.impl.jna.JnaSupportImpl;
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java openjdk-lts-11.0.21+9/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/TimestampedSigner.java	2023-10-06 05:33:33.000000000 +0000
    @@ -49,24 +49,10 @@
     public final class TimestampedSigner extends ContentSigner {
     
         /*
    -     * Object identifier for the subject information access X.509 certificate
    -     * extension.
    -     */
    -    private static final String SUBJECT_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.11";
    -
    -    /*
          * Object identifier for the timestamping access descriptors.
          */
    -    private static final ObjectIdentifier AD_TIMESTAMPING_Id;
    -    static {
    -        ObjectIdentifier tmp = null;
    -        try {
    -            tmp = new ObjectIdentifier("1.3.6.1.5.5.7.48.3");
    -        } catch (IOException e) {
    -            // ignore
    -        }
    -        AD_TIMESTAMPING_Id = tmp;
    -    }
    +    private static final ObjectIdentifier AD_TIMESTAMPING_Id =
    +            ObjectIdentifier.of(KnownOIDs.AD_TimeStamping);
     
         /**
          * Instantiates a content signer that supports timestamped signatures.
    @@ -155,8 +141,8 @@
             }
             // Parse the extensions
             try {
    -            byte[] extensionValue =
    -                tsaCertificate.getExtensionValue(SUBJECT_INFO_ACCESS_OID);
    +            byte[] extensionValue = tsaCertificate.getExtensionValue
    +                    (KnownOIDs.SubjectInfoAccess.value());
                 if (extensionValue == null) {
                     return null;
                 }
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1628,7 +1628,8 @@
             if (!(lower.startsWith("mailto:")
                     || lower.startsWith("http:")
                     || lower.startsWith("https:")
    -                || lower.startsWith("file:"))) {
    +                || lower.startsWith("file:")
    +                || lower.startsWith("ftp:"))) {
                 text = "{@" + (new DocRootTaglet()).getName() + "}/"
                         + redirectPathFromRoot.resolve(text).getPath();
                 text = replaceDocRootDir(text);
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java
    --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java	2023-10-06 05:33:33.000000000 +0000
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2018, 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
    @@ -29,6 +29,7 @@
     import jdk.javadoc.internal.doclets.toolkit.Content;
     import jdk.javadoc.internal.doclets.toolkit.util.DocLink;
     import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
    +import jdk.javadoc.internal.doclets.toolkit.util.Extern;
     
     /**
      * Factory for HTML A elements, both links (with a {@code href} attribute)
    @@ -334,44 +335,7 @@
                 return name.replaceAll(" +", "");
             }
     
    -        StringBuilder sb = new StringBuilder();
    -        for (int i = 0; i < name.length(); i++) {
    -            char ch = name.charAt(i);
    -            switch (ch) {
    -                case '(':
    -                case ')':
    -                case '<':
    -                case '>':
    -                case ',':
    -                    sb.append('-');
    -                    break;
    -                case ' ':
    -                case '[':
    -                    break;
    -                case ']':
    -                    sb.append(":A");
    -                    break;
    -                // Any appearance of $ needs to be substituted with ":D" and not with hyphen
    -                // since a field name "P$$ and a method P(), both valid member names, can end
    -                // up as "P--". A member name beginning with $ needs to be substituted with
    -                // "Z:Z:D".
    -                case '$':
    -                    if (i == 0)
    -                        sb.append("Z:Z");
    -                    sb.append(":D");
    -                    break;
    -                // A member name beginning with _ needs to be prefixed with "Z:Z" since valid anchor
    -                // names can only begin with a letter.
    -                case '_':
    -                    if (i == 0)
    -                        sb.append("Z:Z");
    -                    sb.append(ch);
    -                    break;
    -                default:
    -                    sb.append(ch);
    -            }
    -        }
    -        return sb.toString();
    +        return Extern.getOldFormHtmlName(name);
         }
     
     }
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.css openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.css
    --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.css	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.css	2023-10-06 05:33:33.000000000 +0000
    @@ -1,4 +1,4 @@
    -/*! jQuery UI - v1.13.1 - 2022-05-12
    +/*! jQuery UI - v1.13.2 - 2023-02-27
     * http://jqueryui.com
     * Includes: core.css, autocomplete.css, menu.css
     * Copyright jQuery Foundation and other contributors; Licensed MIT */
    diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.js openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.js
    --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.js	2023-08-23 05:22:04.000000000 +0000
    +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.js	2023-10-06 05:33:33.000000000 +0000
    @@ -1,4 +1,4 @@
    -/*! jQuery UI - v1.13.1 - 2022-05-12
    +/*! jQuery UI - v1.13.2 - 2023-02-27
     * http://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 */
    @@ -20,11 +20,11 @@
     
     $.ui = $.ui || {};
     
    -var version = $.ui.version = "1.13.1";
    +var version = $.ui.version = "1.13.2";
     
     
     /*!
    - * jQuery UI Widget 1.13.1
    + * jQuery UI Widget 1.13.2
      * http://jqueryui.com
      *
      * Copyright jQuery Foundation and other contributors
    @@ -766,7 +766,7 @@
     
     
     /*!
    - * jQuery UI Position 1.13.1
    + * jQuery UI Position 1.13.2
      * http://jqueryui.com
      *
      * Copyright jQuery Foundation and other contributors
    @@ -1263,7 +1263,7 @@
     
     
     /*!
    - * jQuery UI Keycode 1.13.1
    + * jQuery UI Keycode 1.13.2
      * http://jqueryui.com
      *
      * Copyright jQuery Foundation and other contributors
    @@ -1298,7 +1298,7 @@
     
     
     /*!
    - * jQuery UI Unique ID 1.13.1
    + * jQuery UI Unique ID 1.13.2
      * http://jqueryui.com
      *
      * Copyright jQuery Foundation and other contributors
    @@ -1366,7 +1366,7 @@
     
     
     /*!
    - * jQuery UI Menu 1.13.1
    + * jQuery UI Menu 1.13.2
      * http://jqueryui.com
      *
      * Copyright jQuery Foundation and other contributors
    @@ -1385,7 +1385,7 @@
     
     
     var widgetsMenu = $.widget( "ui.menu", {
    -	version: "1.13.1",
    +	version: "1.13.2",
     	defaultElement: "
      ", delay: 300, options: { @@ -2057,7 +2057,7 @@ /*! - * jQuery UI Autocomplete 1.13.1 + * jQuery UI Autocomplete 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors @@ -2076,7 +2076,7 @@ $.widget( "ui.autocomplete", { - version: "1.13.1", + version: "1.13.2", defaultElement: "", options: { appendTo: null, diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.css openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.css --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.css 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.css 2023-10-06 05:33:33.000000000 +0000 @@ -1,4 +1,4 @@ -/*! jQuery UI - v1.13.1 - 2022-05-12 +/*! jQuery UI - v1.13.2 - 2023-02-27 * http://jqueryui.com * Includes: core.css, autocomplete.css, menu.css * Copyright jQuery Foundation and other contributors; Licensed MIT */ diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.js openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.js --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.js 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/jquery/jquery-ui.min.js 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,6 @@ -/*! jQuery UI - v1.13.1 - 2022-05-12 +/*! jQuery UI - v1.13.2 - 2023-02-27 * http://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 */ -!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(x){"use strict";x.ui=x.ui||{};x.ui.version="1.13.1";var n,i=0,l=Array.prototype.hasOwnProperty,a=Array.prototype.slice;x.cleanData=(n=x.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=x._data(i,"events"))&&e.remove&&x(i).triggerHandler("remove");n(t)}),x.widget=function(t,i,e){var s,n,o,l={},a=t.split(".")[0],r=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=x.Widget),Array.isArray(e)&&(e=x.extend.apply(null,[{}].concat(e))),x.expr.pseudos[r.toLowerCase()]=function(t){return!!x.data(t,r)},x[a]=x[a]||{},s=x[a][t],n=x[a][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},x.extend(n,s,{version:e.version,_proto:x.extend({},e),_childConstructors:[]}),(o=new i).options=x.widget.extend({},o.options),x.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}l[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=x.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},l,{constructor:n,namespace:a,widgetName:t,widgetFullName:r}),s?(x.each(s._childConstructors,function(t,e){var i=e.prototype;x.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),x.widget.bridge(t,n),n},x.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n
      "),i=e.children()[0];return x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthC(E(s),E(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})},x.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,l=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=x(t.target),i=x(x.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],x.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=x("
        ").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(x("
        ").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==x.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=x("
        ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(x("
        ").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}});x.ui.autocomplete}); \ No newline at end of file +!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(x){"use strict";x.ui=x.ui||{};x.ui.version="1.13.2";var n,i=0,l=Array.prototype.hasOwnProperty,a=Array.prototype.slice;x.cleanData=(n=x.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=x._data(i,"events"))&&e.remove&&x(i).triggerHandler("remove");n(t)}),x.widget=function(t,i,e){var s,n,o,l={},a=t.split(".")[0],r=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=x.Widget),Array.isArray(e)&&(e=x.extend.apply(null,[{}].concat(e))),x.expr.pseudos[r.toLowerCase()]=function(t){return!!x.data(t,r)},x[a]=x[a]||{},s=x[a][t],n=x[a][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},x.extend(n,s,{version:e.version,_proto:x.extend({},e),_childConstructors:[]}),(o=new i).options=x.widget.extend({},o.options),x.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}l[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=x.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},l,{constructor:n,namespace:a,widgetName:t,widgetFullName:r}),s?(x.each(s._childConstructors,function(t,e){var i=e.prototype;x.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),x.widget.bridge(t,n),n},x.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n
        "),i=e.children()[0];return x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthC(E(s),E(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})},x.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,l=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=x(t.target),i=x(x.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],x.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=x("
          ").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(x("
          ").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==x.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=x("
          ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(x("
          ").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}});x.ui.autocomplete}); \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. * 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,6 +99,11 @@ final boolean relative; /** + * Indicates that docs use old-form of anchors. + */ + final boolean useOldFormId; + + /** * Constructor to build a Extern Item object and map it with the element name. * If the same element name is found in the map, then the first mapped * Item object or offline location will be retained. @@ -108,10 +113,11 @@ * file is picked. * @param relative True if path is URL, false if directory path. */ - Item(String elementName, DocPath path, boolean relative) { + Item(String elementName, DocPath path, boolean relative, boolean useOldFormId) { this.elementName = elementName; this.path = path; this.relative = relative; + this.useOldFormId = useOldFormId; } /** @@ -179,7 +185,7 @@ DocPath p = fnd.relative ? relativepath.resolve(fnd.path).resolve(filename) : fnd.path.resolve(filename); - return new DocLink(p, "is-external=true", memberName); + return new DocLink(p, "is-external=true", fnd.useOldFormId ? getOldFormHtmlName(memberName) : memberName); } /** @@ -212,6 +218,18 @@ return link(url, elemlisturl, reporter, true); } + /** + * Checks if platform docs for the specified version use old-form anchors. + * Old-form anchors are used by Oracle docs for JDKs 8 and 9. + * It can be checked on https://docs.oracle.com/javase//docs/api + * + * @param version + * @return True if docs use old-form anchors + */ + private boolean isOldFormPlatformDocs(int version) { + return 8 == version || 9 == version; + } + /* * Build the extern element list from given URL or the directory path. * Flag error if the "-link" or "-linkoffline" option is already used. @@ -292,7 +310,7 @@ private void readElementListFromURL(String urlpath, URL elemlisturlpath) throws Fault { try { URL link = elemlisturlpath.toURI().resolve(DocPaths.ELEMENT_LIST.getPath()).toURL(); - readElementList(link.openStream(), urlpath, false); + readElementList(link.openStream(), urlpath, false, false); } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(configuration.getText("doclet.MalformedURL", elemlisturlpath.toString()), exc); } catch (IOException exc) { @@ -309,7 +327,7 @@ private void readAlternateURL(String urlpath, URL elemlisturlpath) throws Fault { try { URL link = elemlisturlpath.toURI().resolve(DocPaths.PACKAGE_LIST.getPath()).toURL(); - readElementList(link.openStream(), urlpath, false); + readElementList(link.openStream(), urlpath, false, true); } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(configuration.getText("doclet.MalformedURL", elemlisturlpath.toString()), exc); } catch (IOException exc) { @@ -332,27 +350,27 @@ file = file.resolveAgainst(DocumentationTool.Location.DOCUMENTATION_OUTPUT); } if (file.exists()) { - readElementList(file, path); + readElementList(file, path, false); } else { DocFile file1 = elemListPath.resolve(DocPaths.PACKAGE_LIST); if (!(file1.isAbsolute() || linkoffline)) { file1 = file1.resolveAgainst(DocumentationTool.Location.DOCUMENTATION_OUTPUT); } if (file1.exists()) { - readElementList(file1, path); + readElementList(file1, path, true); } else { throw new Fault(configuration.getText("doclet.File_error", file.getPath()), null); } } } - private void readElementList(DocFile file, String path) throws Fault, DocFileIOException { + private void readElementList(DocFile file, String path, boolean isOldFormDoc) throws Fault, DocFileIOException { try { if (file.canRead()) { boolean pathIsRelative = !isUrl(path) && !DocFile.createFileForInput(configuration, path).isAbsolute(); - readElementList(file.openInputStream(), path, pathIsRelative); + readElementList(file.openInputStream(), path, pathIsRelative, isOldFormDoc); } else { throw new Fault(configuration.getText("doclet.File_error", file.getPath()), null); } @@ -370,7 +388,7 @@ * @param relative Is path relative? * @throws IOException if there is a problem reading or closing the stream */ - private void readElementList(InputStream input, String path, boolean relative) + private void readElementList(InputStream input, String path, boolean relative, boolean isOldFormDoc) throws IOException { try (BufferedReader in = new BufferedReader(new InputStreamReader(input))) { String elemname = null; @@ -382,7 +400,7 @@ elempath = basePath; if (elemname.startsWith(DocletConstants.MODULE_PREFIX)) { moduleName = elemname.replace(DocletConstants.MODULE_PREFIX, ""); - Item item = new Item(moduleName, elempath, relative); + Item item = new Item(moduleName, elempath, relative, isOldFormDoc); moduleItems.put(moduleName, item); } else { DocPath pkgPath = DocPath.create(elemname.replace('.', '/')); @@ -392,7 +410,7 @@ elempath = elempath.resolve(pkgPath); } String actualModuleName = checkLinkCompatibility(elemname, moduleName, path); - Item item = new Item(elemname, elempath, relative); + Item item = new Item(elemname, elempath, relative, isOldFormDoc); packageItems.computeIfAbsent(actualModuleName, k -> new TreeMap<>()) .put(elemname, item); } @@ -455,4 +473,65 @@ } return moduleName == null ? DocletConstants.DEFAULT_ELEMENT_NAME : moduleName; } + + /** + * Converts a name to an old-form HTML name (old-form id). + * + * @param name the string that needs to be converted to a valid HTML name + * @return old-form HTML name + */ + public static String getOldFormHtmlName(String name) { + /* The HTML 4 spec at http://www.w3.org/TR/html4/types.html#h-6.2 mentions + * that the name/id should begin with a letter followed by other valid characters. + * The HTML 5 spec (draft) is more permissive on names/ids where the only restriction + * is that it should be at least one character long and should not contain spaces. + * The spec draft is @ http://www.w3.org/html/wg/drafts/html/master/dom.html#the-id-attribute. + * + * For HTML 4, we need to check for non-characters at the beginning of the name and + * substitute it accordingly, "_" and "$" can appear at the beginning of a member name. + * The method substitutes "$" with "Z:Z:D" and will prefix "_" with "Z:Z". + */ + + if (null == name) + return name; + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < name.length(); i++) { + char ch = name.charAt(i); + switch (ch) { + case '(': + case ')': + case '<': + case '>': + case ',': + sb.append('-'); + break; + case ' ': + case '[': + break; + case ']': + sb.append(":A"); + break; + // Any appearance of $ needs to be substituted with ":D" and not with hyphen + // since a field name "P$$ and a method P(), both valid member names, can end + // up as "P--". A member name beginning with $ needs to be substituted with + // "Z:Z:D". + case '$': + if (i == 0) + sb.append("Z:Z"); + sb.append(":D"); + break; + // A member name beginning with _ needs to be prefixed with "Z:Z" since valid anchor + // names can only begin with a letter. + case '_': + if (i == 0) + sb.append("Z:Z"); + sb.append(ch); + break; + default: + sb.append(ch); + } + } + return sb.toString(); + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/legal/jqueryUI.md openjdk-lts-11.0.21+9/src/jdk.javadoc/share/legal/jqueryUI.md --- openjdk-lts-11.0.20.1+1/src/jdk.javadoc/share/legal/jqueryUI.md 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.javadoc/share/legal/jqueryUI.md 2023-10-06 05:33:33.000000000 +0000 @@ -1,4 +1,4 @@ -## jQuery UI v1.12.1 +## jQuery UI v1.13.2 ### jQuery UI License ``` diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Env.java openjdk-lts-11.0.21+9/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Env.java --- openjdk-lts-11.0.20.1+1/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Env.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Env.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -57,8 +57,8 @@ private static HashMap savedValues = new HashMap(); private static Method atExitMethod; - static void init(String connectSpec, boolean openNow, int flags) { - connection = new VMConnection(connectSpec, flags); + static void init(String connectSpec, boolean openNow, int flags, String extraOptions) { + connection = new VMConnection(connectSpec, flags, extraOptions); if (!connection.isLaunch() || openNow) { connection.open(); } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java openjdk-lts-11.0.21+9/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java --- openjdk-lts-11.0.20.1+1/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -1047,8 +1047,8 @@ /* * Here are examples of jdb command lines and how the options * are interpreted as arguments to the program being debugged. - * arg1 arg2 - * ---- ---- + * arg1 arg2 + * ---- ---- * jdb hello a b a b * jdb hello "a b" a b * jdb hello a,b a,b @@ -1085,14 +1085,10 @@ connectSpec); return; } - connectSpec += "options=" + javaArgs + ","; } try { - if (! connectSpec.endsWith(",")) { - connectSpec += ","; // (Bug ID 4285874) - } - Env.init(connectSpec, launchImmediately, traceFlags); + Env.init(connectSpec, launchImmediately, traceFlags, javaArgs); new TTY(); } catch(Exception e) { MessageOutput.printException("Internal exception:", e); diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/VMConnection.java openjdk-lts-11.0.21+9/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/VMConnection.java --- openjdk-lts-11.0.20.1+1/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/VMConnection.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/VMConnection.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -78,7 +78,8 @@ return null; } - private Map parseConnectorArgs(Connector connector, String argString) { + private Map + parseConnectorArgs(Connector connector, String argString, String extraOptions) { Map arguments = connector.defaultArguments(); /* @@ -121,10 +122,20 @@ */ if (name.equals("options")) { StringBuilder sb = new StringBuilder(); + if (extraOptions != null) { + sb.append(extraOptions).append(" "); + // set extraOptions to null to avoid appending it again + extraOptions = null; + } for (String s : splitStringAtNonEnclosedWhiteSpace(value)) { + boolean wasEnclosed = false; while (isEnclosed(s, "\"") || isEnclosed(s, "'")) { + wasEnclosed = true; s = s.substring(1, s.length() - 1); } + if (wasEnclosed && hasWhitespace(s)) { + s = "\"" + s + "\""; + } sb.append(s); sb.append(" "); } @@ -150,9 +161,26 @@ throw new IllegalArgumentException (MessageOutput.format("Illegal connector argument", argString)); } + if (extraOptions != null) { + // there was no "options" specified in argString + Connector.Argument argument = arguments.get("options"); + if (argument != null) { + argument.setValue(extraOptions); + } + } return arguments; } + private static boolean hasWhitespace(String string) { + int length = string.length(); + for (int i = 0; i < length; i++) { + if (Character.isWhitespace(string.charAt(i))) { + return true; + } + } + return false; + } + private static boolean isEnclosed(String value, String enclosingChar) { if (value.indexOf(enclosingChar) == 0) { int lastIndex = value.lastIndexOf(enclosingChar); @@ -299,7 +327,7 @@ return (pos + 1 == arr.length); } - VMConnection(String connectSpec, int traceFlags) { + VMConnection(String connectSpec, int traceFlags, String extraOptions) { String nameString; String argString; int index = connectSpec.indexOf(':'); @@ -317,7 +345,7 @@ (MessageOutput.format("No connector named:", nameString)); } - connectorArgs = parseConnectorArgs(connector, argString); + connectorArgs = parseConnectorArgs(connector, argString, extraOptions); this.traceFlags = traceFlags; } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java openjdk-lts-11.0.21+9/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java --- openjdk-lts-11.0.20.1+1/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, 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 @@ -902,9 +902,6 @@ private static class HostAwareSslSocketFactory extends SslRMIServerSocketFactory { private final String bindAddress; - private final String[] enabledCipherSuites; - private final String[] enabledProtocols; - private final boolean needClientAuth; private final SSLContext context; private HostAwareSslSocketFactory(String[] enabledCipherSuites, @@ -919,11 +916,9 @@ String[] enabledProtocols, boolean sslNeedClientAuth, String bindAddress) throws IllegalArgumentException { - this.context = ctx; + super(ctx, enabledCipherSuites, enabledProtocols, sslNeedClientAuth); this.bindAddress = bindAddress; - this.enabledProtocols = enabledProtocols; - this.enabledCipherSuites = enabledCipherSuites; - this.needClientAuth = sslNeedClientAuth; + this.context = ctx; checkValues(ctx, enabledCipherSuites, enabledProtocols); } @@ -933,14 +928,15 @@ try { InetAddress addr = InetAddress.getByName(bindAddress); return new SslServerSocket(port, 0, addr, context, - enabledCipherSuites, enabledProtocols, needClientAuth); + this.getEnabledCipherSuites(), this.getEnabledProtocols(), + this.getNeedClientAuth()); } catch (UnknownHostException e) { return new SslServerSocket(port, context, - enabledCipherSuites, enabledProtocols, needClientAuth); + this.getEnabledCipherSuites(), this.getEnabledProtocols(), this.getNeedClientAuth()); } } else { return new SslServerSocket(port, context, - enabledCipherSuites, enabledProtocols, needClientAuth); + this.getEnabledCipherSuites(), this.getEnabledProtocols(), this.getNeedClientAuth()); } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.pack/share/native/libunpack/jni.cpp openjdk-lts-11.0.21+9/src/jdk.pack/share/native/libunpack/jni.cpp --- openjdk-lts-11.0.20.1+1/src/jdk.pack/share/native/libunpack/jni.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.pack/share/native/libunpack/jni.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -314,9 +314,12 @@ JNIEXPORT jlong JNICALL Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) { - unpacker* uPtr = get_unpacker(env, pObj, false); + // There's no need to create a new unpacker here if we don't already have one + // just to immediatly free it afterwards. + unpacker* uPtr = get_unpacker(env, pObj, /* noCreate= */ true); CHECK_EXCEPTION_RETURN_VALUE(uPtr, 0); size_t consumed = uPtr->input_consumed(); + // free_unpacker() will set the unpacker field on 'pObj' to null free_unpacker(env, pObj, uPtr); return consumed; } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/LdapPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/LdapPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/LdapPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/LdapPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. * 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,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; @@ -135,4 +138,30 @@ private LdapName getLdapName(String name) throws InvalidNameException { return new LdapName(name); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if ((name == null) || (nameString == null)) { + throw new InvalidObjectException( + "null name/nameString is illegal"); + } + try { + if (!name.equals(getLdapName(nameString))) { + throw new InvalidObjectException("Inconsistent names"); + } + } catch (InvalidNameException e) { + InvalidObjectException nse = new InvalidObjectException( + "Invalid Name"); + nse.initCause(e); + throw nse; + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/NTDomainPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/NTDomainPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/NTDomainPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/NTDomainPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; /** @@ -120,9 +123,7 @@ return false; NTDomainPrincipal that = (NTDomainPrincipal)o; - if (name.equals(that.getName())) - return true; - return false; + return name.equals(that.getName()); } /** @@ -133,4 +134,23 @@ public int hashCode() { return this.getName().hashCode(); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (name == null) { + java.text.MessageFormat form = new java.text.MessageFormat + (sun.security.util.ResourcesMgr.getAuthResourceString + ("invalid.null.input.value")); + Object[] source = {"name"}; + throw new InvalidObjectException(form.format(source)); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/NTSid.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/NTSid.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/NTSid.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/NTSid.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; /** @@ -80,7 +83,7 @@ (sun.security.util.ResourcesMgr.getAuthResourceString ("Invalid.NTSid.value")); } - sid = new String(stringSid); + sid = stringSid; } /** @@ -128,10 +131,7 @@ return false; NTSid that = (NTSid)o; - if (sid.equals(that.sid)) { - return true; - } - return false; + return sid.equals(that.sid); } /** @@ -142,4 +142,28 @@ public int hashCode() { return sid.hashCode(); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (sid == null) { + java.text.MessageFormat form = new java.text.MessageFormat + (sun.security.util.ResourcesMgr.getAuthResourceString + ("invalid.null.input.value")); + Object[] source = {"stringSid"}; + throw new InvalidObjectException(form.format(source)); + } + if (sid.length() == 0) { + throw new InvalidObjectException + (sun.security.util.ResourcesMgr.getAuthResourceString + ("Invalid.NTSid.value")); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/NTUserPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/NTUserPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/NTUserPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/NTUserPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; /** @@ -114,9 +117,7 @@ return false; NTUserPrincipal that = (NTUserPrincipal)o; - if (name.equals(that.getName())) - return true; - return false; + return name.equals(that.getName()); } /** @@ -127,4 +128,24 @@ public int hashCode() { return this.getName().hashCode(); } + + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (name == null) { + java.text.MessageFormat form = new java.text.MessageFormat + (sun.security.util.ResourcesMgr.getAuthResourceString + ("invalid.null.input.value")); + Object[] source = {"name"}; + throw new InvalidObjectException(form.format(source)); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericGroupPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericGroupPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericGroupPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericGroupPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; import java.util.Objects; @@ -184,10 +187,8 @@ return false; UnixNumericGroupPrincipal that = (UnixNumericGroupPrincipal)o; - if (this.getName().equals(that.getName()) && - this.isPrimaryGroup() == that.isPrimaryGroup()) - return true; - return false; + return this.getName().equals(that.getName()) && + this.isPrimaryGroup() == that.isPrimaryGroup(); } /** @@ -198,4 +199,23 @@ public int hashCode() { return Objects.hash(name, isPrimaryGroup()); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (name == null) { + java.text.MessageFormat form = new java.text.MessageFormat + (sun.security.util.ResourcesMgr.getAuthResourceString + ("invalid.null.input.value")); + Object[] source = {"name"}; + throw new InvalidObjectException(form.format(source)); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericUserPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericUserPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericUserPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixNumericUserPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; /** @@ -146,9 +149,7 @@ return false; UnixNumericUserPrincipal that = (UnixNumericUserPrincipal)o; - if (this.getName().equals(that.getName())) - return true; - return false; + return this.getName().equals(that.getName()); } /** @@ -159,4 +160,23 @@ public int hashCode() { return name.hashCode(); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (name == null) { + java.text.MessageFormat form = new java.text.MessageFormat + (sun.security.util.ResourcesMgr.getAuthResourceString + ("invalid.null.input.value")); + Object[] source = {"name"}; + throw new InvalidObjectException(form.format(source)); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UnixPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; /** @@ -115,9 +118,7 @@ return false; UnixPrincipal that = (UnixPrincipal)o; - if (this.getName().equals(that.getName())) - return true; - return false; + return this.getName().equals(that.getName()); } /** @@ -128,4 +129,23 @@ public int hashCode() { return name.hashCode(); } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (name == null) { + java.text.MessageFormat form = new java.text.MessageFormat + (sun.security.util.ResourcesMgr.getAuthResourceString + ("invalid.null.input.value")); + Object[] source = {"name"}; + throw new InvalidObjectException(form.format(source)); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UserPrincipal.java openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UserPrincipal.java --- openjdk-lts-11.0.20.1+1/src/jdk.security.auth/share/classes/com/sun/security/auth/UserPrincipal.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/src/jdk.security.auth/share/classes/com/sun/security/auth/UserPrincipal.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, 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 @@ -25,6 +25,9 @@ package com.sun.security.auth; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; import java.security.Principal; /** @@ -109,4 +112,19 @@ public String toString() { return name; } + + /** + * Restores the state of this object from the stream. + * + * @param stream the {@code ObjectInputStream} from which data is read + * @throws IOException if an I/O error occurs + * @throws ClassNotFoundException if a serialized class cannot be loaded + */ + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + if (name == null) { + throw new InvalidObjectException("null name is illegal"); + } + } } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/aot/verification/ClassAndLibraryNotMatchTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/aot/verification/ClassAndLibraryNotMatchTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/aot/verification/ClassAndLibraryNotMatchTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/aot/verification/ClassAndLibraryNotMatchTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -92,7 +92,7 @@ private void runAndCheckHelloWorld(String checkString) { ProcessBuilder pb; try { - pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", + pb = ProcessTools.createTestJvm("-cp", ".", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseAOT", "-XX:AOTLibrary=./" + LIB_NAME, HELLO_WORLD_CLASS_NAME); } catch (Exception e) { diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/aot/verification/vmflags/BasicFlagsChange.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/aot/verification/vmflags/BasicFlagsChange.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/aot/verification/vmflags/BasicFlagsChange.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/aot/verification/vmflags/BasicFlagsChange.java 2023-10-06 05:33:33.000000000 +0000 @@ -87,7 +87,7 @@ so, a message like "skipped $pathTolibrary aot library" or "loaded $pathToLibrary aot library" is present for cases of incompatible or compatible flags respectively */ - pb = ProcessTools.createJavaProcessBuilder(true, "-XX:+UnlockExperimentalVMOptions", + pb = ProcessTools.createTestJvm("-XX:+UnlockExperimentalVMOptions", "-XX:+UseAOT", "-XX:+PrintAOT", "-XX:AOTLibrary=./" + libName, option, HelloWorldPrinter.class.getName()); } catch (Exception ex) { diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/arraycopy/stress/TestStressArrayCopy.java 2023-10-06 05:33:33.000000000 +0000 @@ -172,7 +172,7 @@ for (String className : classNames) { // Start a new job { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, mix(c, "-Xmx256m", className).toArray(new String[0])); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(mix(c, "-Xmx256m", className).toArray(new String[0])); Process p = pb.start(); OutputAnalyzer oa = new OutputAnalyzer(p); forks.add(new Fork(p, oa)); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/arraycopy/TestArrayCopyIntrinsicWithUCT.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,312 @@ +/* + * 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 8297730 + * @summary Test taking UCT between array allocation and array copy to report correct exception. + * @library /test/lib + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.arraycopy.TestArrayCopyIntrinsicWithUCT::test* + * compiler.arraycopy.TestArrayCopyIntrinsicWithUCT + */ + +package compiler.arraycopy; + +import jdk.test.lib.Asserts; + +import java.util.function.Function; +import java.util.function.Supplier; + +public class TestArrayCopyIntrinsicWithUCT { + static int zero = 0; + static int zero2 = 0; + static int minusOne = -1; + static int iFld; + static int iFld2; + static boolean flag; + static byte[] byArrNull = null; + static A aFld = null; + + static public void main(String[] args) { + System.out.println("Start"); // Ensure loaded. + new A(); // Ensure loaded + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSize); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSize2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeFldSize); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeFldSize2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeStore); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeStore2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero3); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero4); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero5); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero6); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZero7); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld2); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld3); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld4); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld5); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld6); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroFld7); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeDivZeroNullPointer); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeSizeComplex); + runNegativeSize(TestArrayCopyIntrinsicWithUCT::testNegativeControlFlowNotAllowed); + flag = false; + runNegativeSizeHalf(); + runNegativeSizeHalf(); + } + + static void runNegativeSize(Supplier testMethod) { + try { + testMethod.get(); + Asserts.fail("should throw exception"); + } catch (NegativeArraySizeException e) { + // Expected + } + } + + static void runNegativeSize(Function testMethod) { + try { + testMethod.apply(null); + Asserts.fail("should throw exception"); + } catch (NegativeArraySizeException e) { + // Expected + } + } + + static byte[] testNegativeSize(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = byArr.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSize2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = byArrNull.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeFldSize(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = byArr.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + static byte[] testNegativeFldSize2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = byArrNull.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeStore(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + iFld++; // Since we have a store here, we do not move the allocation down + int len = byArr.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeStore2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + iFld++; // Since we have a store here, we do not move the allocation down + int len = byArrNull.length; // null check trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZero(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZero2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZero3(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero4(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero5(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero6(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZero7(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = 8 / zero / zero2; // 2 div by zero traps would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZeroFld2() { + byte[] byArr = new byte[8]; + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, len); + return b; + } + + static byte[] testNegativeSizeDivZeroFld3(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld4(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld5(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, iFld2); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld6(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroFld7(byte[] byArr) { + byte[] b = new byte[-1]; // throws NegativeArraySizeException + int len = minusOne / zero / zero2; // div by zero trap would fail + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static byte[] testNegativeSizeDivZeroNullPointer(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int x = minusOne / zero / zero2; // div by zero trap would fail + int len = byArr.length; + System.arraycopy(byArr, 0, b, 0, len); + iFld = x; + return b; + } + + static byte[] testNegativeSizeComplex(byte[] byArr) { + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + int x = minusOne / zero; // div by zero trap would fail + int y = aFld.i; + int len = byArr.length; + x = x + aFld.i2 / zero2; + System.arraycopy(byArr, 0, b, 0, x); + iFld = x + y; + return b; + } + + // Optimization not applied because of additional control flow that is not considered safe. + static byte[] testNegativeControlFlowNotAllowed(byte[] byArr) { + int x = 23; + byte[] b = new byte[minusOne]; // throws NegativeArraySizeException + if (flag) { + x = 34; + } + int len = x / zero; + System.arraycopy(byArr, 0, b, 0, 8); + iFld = len; + return b; + } + + static void runNegativeSizeHalf() { + try { + testNegativeSizeHalf(null); + Asserts.fail("should throw exception"); + } catch (NegativeArraySizeException e) { + Asserts.assertTrue(flag, "wrongly caught NegativeArraySizeException"); + } catch (NullPointerException e) { + Asserts.assertFalse(flag, "wrongly caught NullPointerException"); + } + flag = !flag; + } + + static byte[] testNegativeSizeHalf(byte[] byArr) { + int size = flag ? -1 : 1; + byte[] b = new byte[size]; // throws NegativeArraySizeException if size == -1 + int len = byArr.length; // throws NullPointerException if size == 1 + System.arraycopy(byArr, 0, b, 0, len); + return b; + } +} + +class A { + int i, i2; +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/c2/aarch64/TestIntrinsicsRegStress.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/c2/aarch64/TestIntrinsicsRegStress.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/c2/aarch64/TestIntrinsicsRegStress.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/c2/aarch64/TestIntrinsicsRegStress.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2023, 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. + */ + +/* + * @test + * @bug 8307572 + * @summary Verify vector register clobbering in some aarch64 intrinsics + * @library /compiler/patches /test/lib + * @build java.base/java.lang.Helper + * @run main/othervm -Xbatch -XX:CompileThreshold=100 -XX:-TieredCompilation compiler.c2.aarch64.TestIntrinsicsRegStress + */ + +package compiler.c2.aarch64; + +import java.util.Arrays; + +public class TestIntrinsicsRegStress { + + final int LENGTH = 1024; + final int ITER = 10000; + final int NUM = 32; + + byte[] ba; + char[] ca; + char[] cb; + float[] fv; + + String str; + String[] strings; + String needle = "01234567890123456789"; + + public void init() { + ca = new char[LENGTH]; + fv = new float[NUM]; + strings = new String[NUM]; + for (int i = 0; i < LENGTH; i++) { + ca[i] = (char) ('a' + i % NUM); + } + cb = ca.clone(); + str = new String(ca); + for (int i = 0; i < NUM; i++) { + fv[i] = 1; + } + for (int i = 0; i < NUM; i++) { + strings[i] = str.substring(i) + needle; + } + } + + public void checkIndexOf(int iter) { + float t0 = 0; + float t1 = fv[1] * fv[0]; + float t2 = fv[2] * fv[0]; + float t3 = fv[3] * fv[0]; + float t4 = fv[4] * fv[0]; + float t5 = fv[5] * fv[0]; + float t6 = fv[6] * fv[0]; + float t7 = fv[7] * fv[0]; + float t8 = fv[8] * fv[0]; + float t9 = fv[9] * fv[0]; + float t10 = fv[10] * fv[0]; + float t11 = fv[11] * fv[0]; + float t12 = fv[12] * fv[0]; + float t13 = fv[13] * fv[0]; + float t14 = fv[14] * fv[0]; + float t15 = fv[15] * fv[0]; + float t16 = fv[16] * fv[0]; + float t17 = fv[17] * fv[0]; + float t18 = fv[18] * fv[0]; + float t19 = fv[19] * fv[0]; + float t20 = fv[20] * fv[0]; + float t21 = fv[21] * fv[0]; + float t22 = fv[22] * fv[0]; + float t23 = fv[23] * fv[0]; + float t24 = fv[24] * fv[0]; + float t25 = fv[25] * fv[0]; + float t26 = fv[26] * fv[0]; + float t27 = fv[27] * fv[0]; + float t28 = fv[28] * fv[0]; + float t29 = fv[29] * fv[0]; + float t30 = fv[30] * fv[0]; + + int result = strings[iter % NUM].indexOf(needle); + + if (result > LENGTH - NUM / 2) { + // Use fp registers as many as possible and try to make them + // live across above intrinsic function. + t0 += t1 - t2 + t3 - t4 + t5 - t6 + t7 - t8 + t9 - t10 + t11 - t12 + t13 - t14 + t15 + - t16 + t17 - t18 + t19 - t20 + t21 - t22 + t23 - t24 + t25 - t26 + t27 - t28 + + t29 - t30; // 0 + } + fv[31] += t0 + t2 - t11 + t16 - t29; + } + + public void testIndexOf() { + for (int i = 0; i < ITER; i++) { + checkIndexOf(i); + } + } + + public void checkArraysEquals() { + float t0 = 0; + float t1 = fv[1] * fv[0]; + float t2 = fv[2] * fv[0]; + float t3 = fv[3] * fv[0]; + float t4 = fv[4] * fv[0]; + float t5 = fv[5] * fv[0]; + float t6 = fv[6] * fv[0]; + float t7 = fv[7] * fv[0]; + float t8 = fv[8] * fv[0]; + float t9 = fv[9] * fv[0]; + float t10 = fv[10] * fv[0]; + float t11 = fv[11] * fv[0]; + float t12 = fv[12] * fv[0]; + float t13 = fv[13] * fv[0]; + float t14 = fv[14] * fv[0]; + float t15 = fv[15] * fv[0]; + float t16 = fv[16] * fv[0]; + float t17 = fv[17] * fv[0]; + float t18 = fv[18] * fv[0]; + float t19 = fv[19] * fv[0]; + float t20 = fv[20] * fv[0]; + float t21 = fv[21] * fv[0]; + float t22 = fv[22] * fv[0]; + float t23 = fv[23] * fv[0]; + float t24 = fv[24] * fv[0]; + float t25 = fv[25] * fv[0]; + float t26 = fv[26] * fv[0]; + float t27 = fv[27] * fv[0]; + float t28 = fv[28] * fv[0]; + float t29 = fv[29] * fv[0]; + float t30 = fv[30] * fv[0]; + + if (Arrays.equals(ca, cb)) { + // Use fp registers as many as possible and try to make them + // live across above intrinsic function. + t0 += t1 - t2 + t3 - t4 + t5 - t6 + t7 - t8 + t9 - t10 + t11 - t12 + t13 - t14 + t15 + - t16 + t17 - t18 + t19 - t20 + t21 - t22 + t23 - t24 + t25 - t26 + t27 - t28 + + t29 - t30; // 0 + } + fv[31] += t0 + t2 - t11 + t16 - t29; + } + + public void testArraysEquals() { + for (int i = 0; i < ITER; i++) { + checkArraysEquals(); + } + } + + public void checkCompress(int iter) { + float t0 = 0; + float t1 = fv[1] * fv[0]; + float t2 = fv[2] * fv[0]; + float t3 = fv[3] * fv[0]; + float t4 = fv[4] * fv[0]; + float t5 = fv[5] * fv[0]; + float t6 = fv[6] * fv[0]; + float t7 = fv[7] * fv[0]; + float t8 = fv[8] * fv[0]; + float t9 = fv[9] * fv[0]; + float t10 = fv[10] * fv[0]; + float t11 = fv[11] * fv[0]; + float t12 = fv[12] * fv[0]; + float t13 = fv[13] * fv[0]; + float t14 = fv[14] * fv[0]; + float t15 = fv[15] * fv[0]; + float t16 = fv[16] * fv[0]; + float t17 = fv[17] * fv[0]; + float t18 = fv[18] * fv[0]; + float t19 = fv[19] * fv[0]; + float t20 = fv[20] * fv[0]; + float t21 = fv[21] * fv[0]; + float t22 = fv[22] * fv[0]; + float t23 = fv[23] * fv[0]; + float t24 = fv[24] * fv[0]; + float t25 = fv[25] * fv[0]; + float t26 = fv[26] * fv[0]; + float t27 = fv[27] * fv[0]; + float t28 = fv[28] * fv[0]; + float t29 = fv[29] * fv[0]; + float t30 = fv[30] * fv[0]; + + ba = Helper.compressChar(ca, 0, LENGTH, 0, LENGTH); + + if (ba[iter % LENGTH] > (byte) ('a' + 5)) { + // Use fp registers as many as possible and try to make them + // live across above intrinsic function. + t0 += t1 - t2 + t3 - t4 + t5 - t6 + t7 - t8 + t9 - t10 + t11 - t12 + t13 - t14 + t15 + - t16 + t17 - t18 + t19 - t20 + t21 - t22 + t23 - t24 + t25 - t26 + t27 - t28 + + t29 - t30; // 0 + } + fv[31] += t0 + t2 - t11 + t16 - t29; + } + + public void testCompress() { + for (int i = 0; i < ITER; i++) { + checkCompress(i); + } + } + + public void checkInflate(int iter) { + float t0 = 0; + float t1 = fv[1] * fv[0]; + float t2 = fv[2] * fv[0]; + float t3 = fv[3] * fv[0]; + float t4 = fv[4] * fv[0]; + float t5 = fv[5] * fv[0]; + float t6 = fv[6] * fv[0]; + float t7 = fv[7] * fv[0]; + float t8 = fv[8] * fv[0]; + float t9 = fv[9] * fv[0]; + float t10 = fv[10] * fv[0]; + float t11 = fv[11] * fv[0]; + float t12 = fv[12] * fv[0]; + float t13 = fv[13] * fv[0]; + float t14 = fv[14] * fv[0]; + float t15 = fv[15] * fv[0]; + float t16 = fv[16] * fv[0]; + float t17 = fv[17] * fv[0]; + float t18 = fv[18] * fv[0]; + float t19 = fv[19] * fv[0]; + float t20 = fv[20] * fv[0]; + float t21 = fv[21] * fv[0]; + float t22 = fv[22] * fv[0]; + float t23 = fv[23] * fv[0]; + float t24 = fv[24] * fv[0]; + float t25 = fv[25] * fv[0]; + float t26 = fv[26] * fv[0]; + float t27 = fv[27] * fv[0]; + float t28 = fv[28] * fv[0]; + float t29 = fv[29] * fv[0]; + float t30 = fv[30] * fv[0]; + + str.getChars(0, LENGTH, ca, 0); + + if (ca[iter % LENGTH] > (byte) ('a' + NUM / 2)) { + // Use fp registers as many as possible and try to make them + // live across above intrinsic function. + t0 += t1 - t2 + t3 - t4 + t5 - t6 + t7 - t8 + t9 - t10 + t11 - t12 + t13 - t14 + t15 + - t16 + t17 - t18 + t19 - t20 + t21 - t22 + t23 - t24 + t25 - t26 + t27 - t28 + + t29 - t30; // 0 + } + fv[31] += t0 + t2 - t11 + t16 - t29; + } + + public void testInflate() { + for (int i = 0; i < ITER; i++) { + checkInflate(i); + } + } + + public void verifyAndReset() { + if (fv[31] != 1.0) { + throw new RuntimeException("Failed with " + Float.toString(fv[31])); + } else { + System.out.println("Success!"); + } + fv[31] = 1.0f; + } + + public static void main(String[] args) { + TestIntrinsicsRegStress t = new TestIntrinsicsRegStress(); + t.init(); + + t.testIndexOf(); + t.verifyAndReset(); + + t.testArraysEquals(); + t.verifyAndReset(); + + t.testCompress(); + t.verifyAndReset(); + + t.testInflate(); + t.verifyAndReset(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/c2/irTests/TestDebugInfo.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,137 @@ +/* + * 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. + */ + +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * @ignore + * @bug 8201516 + * @summary Verify that debug information in C2 compiled code is correct. + * @library /test/lib / + * @requires vm.compiler2.enabled + * @run driver compiler.c2.irTests.TestDebugInfo + */ +// ignore -- as ir_framework is not in 11. +public class TestDebugInfo { + + public static void main(String[] args) { + TestFramework.runWithFlags("-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints"); + } + + static class MyClass { + final int val; + + @ForceInline + public MyClass(int val) { + this.val = val; + } + + @ForceInline + synchronized void synchronizedMethod(boolean throwIt) { + if (throwIt) { + throw new RuntimeException(); // Make sure there is an exception state + } + } + } + + static Object[] array = new Object[3]; + static MyClass myVal = new MyClass(42); + + // Verify that the MemBarRelease emitted at the MyClass constructor exit + // does not incorrectly reference the caller method in its debug information. + @Test + @IR(failOn = {"MemBarRelease.*testFinalFieldInit.*bci:-1"}, phase = CompilePhase.BEFORE_MATCHING) + public static void testFinalFieldInit() { + array[0] = new MyClass(42); + array[1] = new MyClass(42); + array[2] = new MyClass(42); + } + + // Verify that the MemBarReleaseLock emitted at the synchronizedMethod exit + // does not incorrectly reference the caller method in its debug information. + @Test + @IR(failOn = {"MemBarReleaseLock.*testSynchronized.*bci:-1"}, phase = CompilePhase.BEFORE_MATCHING) + public static void testSynchronized() { + try { + myVal.synchronizedMethod(false); + myVal.synchronizedMethod(true); + } catch (Exception e) { + // Ignore + } + } + + static byte b0 = 0; + static byte b1 = 0; + static byte b2 = 0; + static byte b3 = 0; + + @ForceInline + public static Integer useless3(Integer val) { + return ++val; + } + + @ForceInline + public static Integer useless2(Integer val) { + return useless3(useless3(useless3(useless3(useless3(useless3(useless3(useless3(val)))))))); + } + + @ForceInline + public static Integer useless1(Integer val) { + return useless2(useless2(useless2(useless2(useless2(useless2(useless2(useless2(val)))))))); + } + + @ForceInline + public static void useful3() { + b3 = 3; + } + + @ForceInline + public static void useful2() { + useful3(); + b2 = 2; + } + + @ForceInline + public static void useful1() { + useful2(); + b1 = 1; + } + + // Verify that RenumberLiveNodes preserves the debug information side table. + @Test + @IR(counts = {"StoreB.*name=b3.*useful3.*bci:1.*useful2.*bci:0.*useful1.*bci:0.*testRenumberLiveNodes.*bci:9", "= 1"}, phase = CompilePhase.BEFORE_MATCHING) + @IR(counts = {"StoreB.*name=b2.*useful2.*bci:4.*useful1.*bci:0.*testRenumberLiveNodes.*bci:9", "= 1"}, phase = CompilePhase.BEFORE_MATCHING) + @IR(counts = {"StoreB.*name=b1.*useful1.*bci:4.*testRenumberLiveNodes.*bci:9", "= 1"}, phase = CompilePhase.BEFORE_MATCHING) + @IR(counts = {"StoreB.*name=b0.*testRenumberLiveNodes.*bci:13", "= 1"}, phase = CompilePhase.BEFORE_MATCHING) + public static void testRenumberLiveNodes() { + // This generates ~3700 useless nodes to trigger RenumberLiveNodes + useless1(42); + + // Do something useful + useful1(); + b0 = 0; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/c2/Test6905845.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/c2/Test6905845.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/c2/Test6905845.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/c2/Test6905845.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,6 +26,7 @@ * @bug 6905845 * @summary Server VM improperly optimizing away loop. * + * @requires vm.opt.TieredStopAtLevel != 3 * @run main/timeout=480 compiler.c2.Test6905845 */ diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java 2023-10-06 05:33:33.000000000 +0000 @@ -137,11 +137,10 @@ options.add(needCoreDump ? ENABLE_COREDUMP_ON_CRASH : DISABLE_COREDUMP_ON_CRASH); options.add(VERSION_OPTION); if (needCoreDump) { - crashOut = ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix( + crashOut = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix( RUN_SHELL_NO_LIMIT, options.toArray(new String[0]))); } else { - crashOut = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(true, - options)); + crashOut = ProcessTools.executeProcess(ProcessTools.createTestJvm(options)); } crashOutputString = crashOut.getOutput(); Asserts.assertNotEquals(crashOut.getExitValue(), 0, "Crash JVM exits gracefully"); @@ -185,7 +184,7 @@ List allAdditionalOpts = new ArrayList<>(); allAdditionalOpts.addAll(Arrays.asList(REPLAY_OPTIONS)); allAdditionalOpts.addAll(Arrays.asList(additionalVmOpts)); - OutputAnalyzer oa = ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix( + OutputAnalyzer oa = ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix( RUN_SHELL_ZERO_LIMIT, allAdditionalOpts.toArray(new String[0]))); return oa.getExitValue(); } catch (Throwable t) { @@ -285,9 +284,9 @@ return null; } - private String[] getTestJavaCommandlineWithPrefix(String prefix, String... args) { + private String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) { try { - String cmd = ProcessTools.getCommandLine(ProcessTools.createJavaProcessBuilder(true, args)); + String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args)); return new String[]{"sh", "-c", prefix + (Platform.isWindows() ? cmd.replace('\\', '/').replace(";", "\\;").replace("|", "\\|") : cmd)}; } catch(Throwable t) { diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/ciReplay/SABase.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/ciReplay/SABase.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/ciReplay/SABase.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/ciReplay/SABase.java 2023-10-06 05:33:33.000000000 +0000 @@ -57,7 +57,7 @@ } ProcessBuilder pb; try { - pb = ProcessTools.createJavaProcessBuilder(true, "--add-modules", "jdk.hotspot.agent", + pb = ProcessTools.createTestJvm("--add-modules", "jdk.hotspot.agent", "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED", "sun.jvm.hotspot.CLHSDB", JDKToolFinder.getTestJDKTool("java"), TEST_CORE_FILE_NAME); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java 2023-10-06 05:33:33.000000000 +0000 @@ -112,7 +112,7 @@ String classPath = String.join(File.pathSeparator, System.getProperty("java.class.path"), String.join(File.separator, libsDir, MXTOOL_JARFILE)); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-cp", classPath, "com.oracle.mxtool.junit.FindClassesByAnnotatedMethods", graalUnitTestFilePath, testAnnotationName); @@ -263,8 +263,7 @@ javaFlags.add("@"+GENERATED_TESTCLASSES_FILENAME); - ProcessBuilder javaPB = ProcessTools.createJavaProcessBuilder(true, - javaFlags); + ProcessBuilder javaPB = ProcessTools.createTestJvm(javaFlags); System.out.println("INFO: run command: " + String.join(" ", javaPB.command())); OutputAnalyzer outputAnalyzer = new OutputAnalyzer(javaPB.start()); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIndexOfCharIntrinsics.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,74 @@ +/* + * 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. 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 8301491 + * @summary Check for correct return value when calling indexOfChar intrinsics with negative value. + * @library /test/lib + * + * @run main/othervm -XX:CompileCommand=quiet + * -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,compiler.intrinsics.string.TestStringIndexOfCharIntrinsics::testIndexOfChar* + * -XX:CompileCommand=inline,java.lang.String*::indexOf* + * -XX:PerBytecodeTrapLimit=20000 + * -XX:PerMethodTrapLimit=20000 + * compiler.intrinsics.string.TestStringIndexOfCharIntrinsics + */ + +package compiler.intrinsics.string; + +import jdk.test.lib.Asserts; + +public class TestStringIndexOfCharIntrinsics { + + static byte byArr[] = new byte[500]; + + public static void main(String[] args) { + for (int j = 0; j < byArr.length; j++) { + byArr[j] = (byte)j; + } + // Test value for aarch64 + byArr[24] = 0x7; + byArr[23] = -0x80; + // Warmup + for (int i = 0; i < 10000; i++) { + testIndexOfCharArg(i); + testIndexOfCharConst(); + } + Asserts.assertEquals(testIndexOfCharConst() , -1, "must be -1 (character not found)"); + Asserts.assertEquals(testIndexOfCharArg(-2147483641) , -1, "must be -1 (character not found)"); + } + + static int testIndexOfCharConst() { + String s = new String(byArr); + return s.indexOf(-2147483641); + } + + static int testIndexOfCharArg(int ch) { + String s = new String(byArr); + return s.indexOf(ch); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyCountedLoop.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyCountedLoop.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyCountedLoop.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/loopopts/TestRemoveEmptyCountedLoop.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 8289748 + * @summary SIGFPE caused by C2 IdealLoopTree::do_remove_empty_loop + * @key stress randomness + * + * @run main/othervm -XX:-TieredCompilation -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+StressGCM + * -XX:CompileCommand=compileonly,compiler.loopopts.TestRemoveEmptyCountedLoop::test* + * compiler.loopopts.TestRemoveEmptyCountedLoop + */ + +package compiler.loopopts; + +public class TestRemoveEmptyCountedLoop { + + public static void test1() { + int k = 3; + for (int i=9; i>0; i--) { + for (int j=2; j0; i--) { + int j = 2; + do { + try { + k = k; + k = (1 % j); + } catch (Exception e) {} + } while (++j < i); + } + } + + public static void main(String[] args) { + test1(); + test2(); + System.out.println("Test passed."); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/loopstripmining/TestAddPAtOuterLoopHead.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * 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 8303511 + * @summary C2: assert(get_ctrl(n) == cle_out) during unrolling + * @requires vm.gc.Parallel + * @run main/othervm -XX:-BackgroundCompilation -XX:+UseParallelGC TestAddPAtOuterLoopHead + */ + + +import java.util.Arrays; + +public class TestAddPAtOuterLoopHead { + public static void main(String[] args) { + boolean[] flags1 = new boolean[1000]; + boolean[] flags2 = new boolean[1000]; + Arrays.fill(flags2, true); + for (int i = 0; i < 20_000; i++) { + testHelper(42, 42, 43); + test(flags1); + test(flags2); + } + } + + private static int test(boolean[] flags) { + int[] array = new int[1000]; + + int k; + for (k = 0; k < 10; k++) { + for (int i = 0; i < 2; i++) { + } + } + k = k / 10; + int m; + for (m = 0; m < 2; m++) { + for (int i = 0; i < 2; i++) { + for (int j = 0; j < 2; j++) { + } + } + } + + + int v = 0; + for (int j = 0; j < 2; j++) { + for (int i = 0; i < 998; i += k) { + int l = testHelper(m, j, i); + v = array[i + l]; + if (flags[i]) { + return v; + } + } + } + + return v; + } + + private static int testHelper(int m, int j, int i) { + return m == 2 ? j : i; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/runtime/cr8015436/Driver8015436.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/runtime/cr8015436/Driver8015436.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/runtime/cr8015436/Driver8015436.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/runtime/cr8015436/Driver8015436.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,8 +30,8 @@ public static void main(String args[]) { OutputAnalyzer oa; try { - oa = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder( - /* add test vm options */ true, Test8015436.class.getName())); + oa = ProcessTools.executeProcess(ProcessTools.createTestJvm( + Test8015436.class.getName())); } catch (Exception ex) { throw new Error("TESTBUG: exception while running child process: " + ex, ex); } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/startup/NumCompilerThreadsCheck.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/startup/NumCompilerThreadsCheck.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/startup/NumCompilerThreadsCheck.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/startup/NumCompilerThreadsCheck.java 2023-10-06 05:33:33.000000000 +0000 @@ -46,11 +46,6 @@ String expectedOutput = "outside the allowed range"; out.shouldContain(expectedOutput); - - if (Platform.isZero()) { - String expectedLowWaterMarkText = "must be at least 0"; - out.shouldContain(expectedLowWaterMarkText); - } } } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/types/correctness/OffTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/types/correctness/OffTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/types/correctness/OffTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/types/correctness/OffTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -87,7 +87,7 @@ OPTIONS[TYPE_PROFILE_INDEX] = typeProfileLevel; OPTIONS[USE_TYPE_SPECULATION_INDEX] = useTypeSpeculation; OPTIONS[PROFILING_TYPE_INDEX] = type.name(); - ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(/* addTestVmOptions= */ true, OPTIONS); + ProcessBuilder processBuilder = ProcessTools.createTestJvm(OPTIONS); OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start()); outputAnalyzer.shouldHaveExitValue(0); } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/generate-unsafe-access-tests.sh openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/generate-unsafe-access-tests.sh --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/generate-unsafe-access-tests.sh 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/generate-unsafe-access-tests.sh 2023-10-06 05:33:33.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/bash # -# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ # questions. # -javac -d . ../../../../jdk/make/src/classes/build/tools/spp/Spp.java +javac -d . ../../../../../make/jdk/src/classes/build/tools/spp/Spp.java SPP=build.tools.spp.Spp @@ -123,8 +123,10 @@ args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3" echo $args + out=${Qualifier}UnsafeAccessTest${Type}.java + rm -rf "$out" java $SPP -nel -K$Qualifier -Dpackage=$package -DQualifier=$Qualifier -Dmodule=$module \ - $args -iX-UnsafeAccessTest.java.template -o${Qualifier}UnsafeAccessTest${Type}.java + $args -iX-UnsafeAccessTest.java.template -o$out done } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestBoolean.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBooleanPlain(base, offset, true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = UNSAFE.getBoolean(base, offset); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetBooleanPlain(base, offset, true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); + boolean x = UNSAFE.getBoolean(base, offset); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBooleanAcquire(base, offset, false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); + boolean x = UNSAFE.getBoolean(base, offset); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = UNSAFE.weakCompareAndSetBooleanAcquire(base, offset, false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = UNSAFE.getBoolean(base, offset); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBooleanRelease(base, offset, true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = UNSAFE.getBoolean(base, offset); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = UNSAFE.weakCompareAndSetBooleanRelease(base, offset, true, false); + assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); + boolean x = UNSAFE.getBoolean(base, offset); + assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBoolean(base, offset, false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); + boolean x = UNSAFE.getBoolean(base, offset); + assertEquals(x, true, "success weakCompareAndSet boolean"); + } + + { + boolean success = UNSAFE.weakCompareAndSetBoolean(base, offset, false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = UNSAFE.getBoolean(base, offset); - assertEquals(x, true, "weakCompareAndSet boolean"); + assertEquals(x, true, "failing weakCompareAndSet boolean value"); } UNSAFE.putBoolean(base, offset, false); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestByte.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -241,9 +241,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetBytePlain(base, offset, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = UNSAFE.getByte(base, offset); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetBytePlain(base, offset, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); + byte x = UNSAFE.getByte(base, offset); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -251,9 +258,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetByteAcquire(base, offset, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); + byte x = UNSAFE.getByte(base, offset); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = UNSAFE.weakCompareAndSetByteAcquire(base, offset, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = UNSAFE.getByte(base, offset); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -261,9 +275,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetByteRelease(base, offset, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = UNSAFE.getByte(base, offset); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = UNSAFE.weakCompareAndSetByteRelease(base, offset, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetRelease byte"); + byte x = UNSAFE.getByte(base, offset); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); } { @@ -271,9 +292,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetByte(base, offset, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); + byte x = UNSAFE.getByte(base, offset); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + } + + { + boolean success = UNSAFE.weakCompareAndSetByte(base, offset, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = UNSAFE.getByte(base, offset); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); } UNSAFE.putByte(base, offset, (byte)0x23); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestChar.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -259,9 +259,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetCharPlain(base, offset, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = UNSAFE.getChar(base, offset); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetCharPlain(base, offset, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); + char x = UNSAFE.getChar(base, offset); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -269,9 +276,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetCharAcquire(base, offset, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); + char x = UNSAFE.getChar(base, offset); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = UNSAFE.weakCompareAndSetCharAcquire(base, offset, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = UNSAFE.getChar(base, offset); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -279,9 +293,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetCharRelease(base, offset, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = UNSAFE.getChar(base, offset); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = UNSAFE.weakCompareAndSetCharRelease(base, offset, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetRelease char"); + char x = UNSAFE.getChar(base, offset); + assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); } { @@ -289,9 +310,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetChar(base, offset, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); + char x = UNSAFE.getChar(base, offset); + assertEquals(x, '\u0123', "success weakCompareAndSet char"); + } + + { + boolean success = UNSAFE.weakCompareAndSetChar(base, offset, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); char x = UNSAFE.getChar(base, offset); - assertEquals(x, '\u0123', "weakCompareAndSet char"); + assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); } UNSAFE.putChar(base, offset, '\u4567'); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestDouble.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -241,9 +241,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDoublePlain(base, offset, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = UNSAFE.getDouble(base, offset); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetDoublePlain(base, offset, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); + double x = UNSAFE.getDouble(base, offset); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -251,9 +258,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDoubleAcquire(base, offset, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = UNSAFE.getDouble(base, offset); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = UNSAFE.weakCompareAndSetDoubleAcquire(base, offset, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = UNSAFE.getDouble(base, offset); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -261,9 +275,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDoubleRelease(base, offset, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = UNSAFE.getDouble(base, offset); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = UNSAFE.weakCompareAndSetDoubleRelease(base, offset, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); + double x = UNSAFE.getDouble(base, offset); + assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); } { @@ -271,9 +292,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetDouble(base, offset, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = UNSAFE.getDouble(base, offset); + assertEquals(x, 1.0d, "success weakCompareAndSet double"); + } + + { + boolean success = UNSAFE.weakCompareAndSetDouble(base, offset, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = UNSAFE.getDouble(base, offset); - assertEquals(x, 1.0d, "weakCompareAndSet double"); + assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); } UNSAFE.putDouble(base, offset, 2.0d); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestFloat.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -241,9 +241,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloatPlain(base, offset, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = UNSAFE.getFloat(base, offset); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetFloatPlain(base, offset, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); + float x = UNSAFE.getFloat(base, offset); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -251,9 +258,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloatAcquire(base, offset, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = UNSAFE.getFloat(base, offset); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = UNSAFE.weakCompareAndSetFloatAcquire(base, offset, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = UNSAFE.getFloat(base, offset); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -261,9 +275,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloatRelease(base, offset, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = UNSAFE.getFloat(base, offset); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = UNSAFE.weakCompareAndSetFloatRelease(base, offset, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); + float x = UNSAFE.getFloat(base, offset); + assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); } { @@ -271,9 +292,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetFloat(base, offset, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = UNSAFE.getFloat(base, offset); + assertEquals(x, 1.0f, "success weakCompareAndSet float"); + } + + { + boolean success = UNSAFE.weakCompareAndSetFloat(base, offset, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = UNSAFE.getFloat(base, offset); - assertEquals(x, 1.0f, "weakCompareAndSet float"); + assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); } UNSAFE.putFloat(base, offset, 2.0f); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -259,9 +259,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetIntPlain(base, offset, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = UNSAFE.getInt(base, offset); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetIntPlain(base, offset, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); + int x = UNSAFE.getInt(base, offset); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -269,9 +276,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetIntAcquire(base, offset, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = UNSAFE.getInt(base, offset); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = UNSAFE.weakCompareAndSetIntAcquire(base, offset, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = UNSAFE.getInt(base, offset); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -279,9 +293,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetIntRelease(base, offset, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = UNSAFE.getInt(base, offset); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = UNSAFE.weakCompareAndSetIntRelease(base, offset, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); + int x = UNSAFE.getInt(base, offset); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); } { @@ -289,9 +310,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetInt(base, offset, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = UNSAFE.getInt(base, offset); + assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + } + + { + boolean success = UNSAFE.weakCompareAndSetInt(base, offset, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = UNSAFE.getInt(base, offset); - assertEquals(x, 0x01234567, "weakCompareAndSet int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); } UNSAFE.putInt(base, offset, 0x89ABCDEF); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestLong.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -259,9 +259,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLongPlain(base, offset, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = UNSAFE.getLong(base, offset); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetLongPlain(base, offset, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); + long x = UNSAFE.getLong(base, offset); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -269,9 +276,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLongAcquire(base, offset, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = UNSAFE.getLong(base, offset); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = UNSAFE.weakCompareAndSetLongAcquire(base, offset, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = UNSAFE.getLong(base, offset); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -279,9 +293,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLongRelease(base, offset, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = UNSAFE.getLong(base, offset); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = UNSAFE.weakCompareAndSetLongRelease(base, offset, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); + long x = UNSAFE.getLong(base, offset); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); } { @@ -289,9 +310,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetLong(base, offset, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = UNSAFE.getLong(base, offset); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + } + + { + boolean success = UNSAFE.weakCompareAndSetLong(base, offset, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = UNSAFE.getLong(base, offset); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); } UNSAFE.putLong(base, offset, 0xCAFEBABECAFEBABEL); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestObject.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetObjectPlain(base, offset, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain Object"); + assertEquals(success, true, "success weakCompareAndSetPlain Object"); Object x = UNSAFE.getObject(base, offset); - assertEquals(x, "bar", "weakCompareAndSetPlain Object value"); + assertEquals(x, "bar", "success weakCompareAndSetPlain Object value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetObjectPlain(base, offset, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain Object"); + Object x = UNSAFE.getObject(base, offset); + assertEquals(x, "bar", "failing weakCompareAndSetPlain Object value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetObjectAcquire(base, offset, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire Object"); + assertEquals(success, true, "success weakCompareAndSetAcquire Object"); + Object x = UNSAFE.getObject(base, offset); + assertEquals(x, "foo", "success weakCompareAndSetAcquire Object"); + } + + { + boolean success = UNSAFE.weakCompareAndSetObjectAcquire(base, offset, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire Object"); Object x = UNSAFE.getObject(base, offset); - assertEquals(x, "foo", "weakCompareAndSetAcquire Object"); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire Object value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetObjectRelease(base, offset, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease Object"); + assertEquals(success, true, "success weakCompareAndSetRelease Object"); Object x = UNSAFE.getObject(base, offset); - assertEquals(x, "bar", "weakCompareAndSetRelease Object"); + assertEquals(x, "bar", "success weakCompareAndSetRelease Object"); + } + + { + boolean success = UNSAFE.weakCompareAndSetObjectRelease(base, offset, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetRelease Object"); + Object x = UNSAFE.getObject(base, offset); + assertEquals(x, "bar", "failing weakCompareAndSetRelease Object value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetObject(base, offset, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet Object"); + assertEquals(success, true, "success weakCompareAndSet Object"); + Object x = UNSAFE.getObject(base, offset); + assertEquals(x, "foo", "success weakCompareAndSet Object"); + } + + { + boolean success = UNSAFE.weakCompareAndSetObject(base, offset, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet Object"); Object x = UNSAFE.getObject(base, offset); - assertEquals(x, "foo", "weakCompareAndSet Object"); + assertEquals(x, "foo", "failing weakCompareAndSet Object value"); } UNSAFE.putObject(base, offset, "bar"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/JdkInternalMiscUnsafeAccessTestShort.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -259,9 +259,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShortPlain(base, offset, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = UNSAFE.getShort(base, offset); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = UNSAFE.weakCompareAndSetShortPlain(base, offset, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); + short x = UNSAFE.getShort(base, offset); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -269,9 +276,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShortAcquire(base, offset, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); + short x = UNSAFE.getShort(base, offset); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = UNSAFE.weakCompareAndSetShortAcquire(base, offset, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = UNSAFE.getShort(base, offset); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -279,9 +293,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShortRelease(base, offset, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = UNSAFE.getShort(base, offset); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = UNSAFE.weakCompareAndSetShortRelease(base, offset, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetRelease short"); + short x = UNSAFE.getShort(base, offset); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); } { @@ -289,9 +310,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSetShort(base, offset, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); + short x = UNSAFE.getShort(base, offset); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + } + + { + boolean success = UNSAFE.weakCompareAndSetShort(base, offset, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); short x = UNSAFE.getShort(base, offset); - assertEquals(x, (short)0x0123, "weakCompareAndSet short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); } UNSAFE.putShort(base, offset, (short)0x4567); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestBoolean.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestByte.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestChar.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestDouble.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestFloat.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestInt.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestLong.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestObject.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/SunMiscUnsafeAccessTestShort.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/compiler/unsafe/X-UnsafeAccessTest.java.template 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -303,9 +303,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$Type$Plain(base, offset, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = UNSAFE.get$Type$(base, offset); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = UNSAFE.weakCompareAndSet$Type$Plain(base, offset, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); + $type$ x = UNSAFE.get$Type$(base, offset); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -313,9 +320,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$Type$Acquire(base, offset, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = UNSAFE.get$Type$(base, offset); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = UNSAFE.weakCompareAndSet$Type$Acquire(base, offset, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = UNSAFE.get$Type$(base, offset); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -323,9 +337,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$Type$Release(base, offset, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = UNSAFE.get$Type$(base, offset); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = UNSAFE.weakCompareAndSet$Type$Release(base, offset, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); + $type$ x = UNSAFE.get$Type$(base, offset); + assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); } { @@ -333,9 +354,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = UNSAFE.weakCompareAndSet$Type$(base, offset, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = UNSAFE.get$Type$(base, offset); + assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + } + + { + boolean success = UNSAFE.weakCompareAndSet$Type$(base, offset, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = UNSAFE.get$Type$(base, offset); - assertEquals(x, $value1$, "weakCompareAndSet $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); } #end[JdkInternalMisc] diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, 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 @@ -35,23 +35,26 @@ * jdk.jartool/sun.tools.jar * @build AttemptOOM sun.hotspot.WhiteBox PrintContainerInfo CheckOperatingSystemMXBean * @run driver ClassFileInstaller -jar whitebox.jar sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission - * @run driver TestMemoryAwareness + * @run main/othervm -Xbootclasspath/a:whitebox.jar -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestMemoryAwareness */ import jdk.test.lib.containers.docker.Common; import jdk.test.lib.containers.docker.DockerRunOptions; import jdk.test.lib.containers.docker.DockerTestUtils; +import sun.hotspot.WhiteBox; import jdk.test.lib.process.OutputAnalyzer; import static jdk.test.lib.Asserts.assertNotNull; public class TestMemoryAwareness { private static final String imageName = Common.imageName("memory"); + private static final WhiteBox wb = WhiteBox.getWhiteBox(); - private static String getHostMaxMemory() throws Exception { - DockerRunOptions opts = Common.newOpts(imageName); - String goodMem = Common.run(opts).firstMatch("total physical memory: (\\d+)", 1); - assertNotNull(goodMem, "no match for 'total physical memory' in trace output"); - return goodMem; + private static String getHostMaxMemory() { + return Long.valueOf(wb.hostPhysicalMemory()).toString(); + } + + private static String getHostSwap() { + return Long.valueOf(wb.hostPhysicalSwap()).toString(); } public static void main(String[] args) throws Exception { @@ -92,10 +95,9 @@ "200M", Integer.toString(((int) Math.pow(2, 20)) * (200 - 100)), true /* additional cgroup fs mounts */ ); - final String hostMaxMem = getHostMaxMemory(); - testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem); - testMetricsIgnoresMemLimitExceedingPhysicalMemory(hostMaxMem); - testContainerMemExceedsPhysical(hostMaxMem); + testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory(); + testMetricsExceedingPhysicalMemory(); + testContainerMemExceedsPhysical(); } finally { if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { DockerTestUtils.removeDockerImage(imageName); @@ -122,9 +124,10 @@ // JDK-8292083 // Ensure that Java ignores container memory limit values above the host's physical memory. - private static void testContainerMemExceedsPhysical(final String hostMaxMem) + private static void testContainerMemExceedsPhysical() throws Exception { Common.logNewTestCase("container memory limit exceeds physical memory"); + String hostMaxMem = getHostMaxMemory(); String badMem = hostMaxMem + "0"; // set a container memory limit to the bad value DockerRunOptions opts = Common.newOpts(imageName) @@ -204,12 +207,17 @@ .shouldMatch("OperatingSystemMXBean\\.getFreePhysicalMemorySize: [1-9][0-9]+"); // in case of warnings like : "Your kernel does not support swap limit capabilities // or the cgroup is not mounted. Memory limited without swap." - // the getTotalSwapSpaceSize and getFreeSwapSpaceSize return the system - // values as the container setup isn't supported in that case. + // the getTotalSwapSpaceSize either returns the system (or host) values, or 0 + // if a container memory limit is in place and gets detected. A value of 0 is because, + // Metrics.getMemoryLimit() returns the same value as Metrics.getMemoryAndSwapLimit(). + // + // getFreeSwapSpaceSize() are a function of what getTotalSwapSpaceSize() returns. Either + // a number > 0, or 0 if getTotalSwapSpaceSize() == 0. try { out.shouldContain("OperatingSystemMXBean.getTotalSwapSpaceSize: " + expectedSwap); } catch(RuntimeException ex) { - out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: [0-9]+"); + String hostSwap = getHostSwap(); + out.shouldMatch("OperatingSystemMXBean.getTotalSwapSpaceSize: (0|" + hostSwap + ")"); } try { out.shouldMatch("OperatingSystemMXBean\\.getFreeSwapSpaceSize: [1-9][0-9]+"); @@ -220,17 +228,18 @@ // JDK-8292541: Ensure OperatingSystemMXBean ignores container memory limits above the host's physical memory. - private static void testOperatingSystemMXBeanIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem) + private static void testOSMXBeanIgnoresMemLimitExceedingPhysicalMemory() throws Exception { + String hostMaxMem = getHostMaxMemory(); String badMem = hostMaxMem + "0"; testOperatingSystemMXBeanAwareness(badMem, hostMaxMem, badMem, hostMaxMem); } // JDK-8292541: Ensure Metrics ignores container memory limits above the host's physical memory. - private static void testMetricsIgnoresMemLimitExceedingPhysicalMemory(final String hostMaxMem) + private static void testMetricsExceedingPhysicalMemory() throws Exception { Common.logNewTestCase("Metrics ignore container memory limit exceeding physical memory"); - String badMem = hostMaxMem + "0"; + String badMem = getHostMaxMemory() + "0"; DockerRunOptions opts = Common.newOpts(imageName) .addJavaOpts("-XshowSettings:system") .addDockerOpts("--memory", badMem); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java 2023-10-06 05:33:33.000000000 +0000 @@ -85,10 +85,14 @@ // capabilities or the cgroup is not mounted. Memory limited without swap." // we only have Memory and Swap Limit is: in the output try { - out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit) - .shouldContain( + 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"); + } else { + out.shouldContain("Memory and Swap Limit is: " + expectedReadLimit) + .shouldContain( "Memory and Swap Limit has been reset to " + expectedResetLimit + " because swappiness is 0") - .shouldContain("Memory & Swap Limit: " + expectedLimit); + .shouldContain("Memory & Swap Limit: " + expectedLimit); + } } catch (RuntimeException ex) { System.out.println("Expected Memory and Swap Limit output missing."); System.out.println("You may need to add 'cgroup_enable=memory swapaccount=1' to the Linux kernel boot parameters."); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/arguments/GCArguments.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/arguments/GCArguments.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/arguments/GCArguments.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/arguments/GCArguments.java 2023-10-06 05:33:33.000000000 +0000 @@ -67,22 +67,18 @@ } static public ProcessBuilder createJavaProcessBuilder(List arguments) { - return createJavaProcessBuilder(false, arguments); + return createJavaProcessBuilder(arguments.toArray(String[]::new)); } - static public ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, - List arguments) { - return createJavaProcessBuilder(addTestVmAndJavaOptions, - arguments.toArray(String[]::new)); + static public ProcessBuilder createJavaProcessBuilder(String... arguments) { + return ProcessTools.createJavaProcessBuilder(withDefaults(arguments)); } - static public ProcessBuilder createJavaProcessBuilder(String... arguments) { - return createJavaProcessBuilder(false, arguments); + static public ProcessBuilder createTestJvm(List arguments) { + return createTestJvm(arguments.toArray(String[]::new)); } - static public ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, - String... arguments) { - return ProcessTools.createJavaProcessBuilder(addTestVmAndJavaOptions, - withDefaults(arguments)); + static public ProcessBuilder createTestJvm(String... arguments) { + return ProcessTools.createTestJvm(withDefaults(arguments)); } } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java 2023-10-06 05:33:33.000000000 +0000 @@ -41,8 +41,7 @@ public class TestUseNUMAInterleaving { public static void main(String[] args) throws Exception { - ProcessBuilder pb = GCArguments.createJavaProcessBuilder( - true, + ProcessBuilder pb = GCArguments.createTestJvm( "-XX:+UseNUMA", "-XX:+PrintFlagsFinal", "-version"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/mixedgc/TestLogging.java 2023-10-06 05:33:33.000000000 +0000 @@ -95,8 +95,7 @@ Collections.addAll(testOpts, extraFlags); testOpts.add(MixedGCProvoker.class.getName()); System.out.println(testOpts); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(false, - testOpts); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(testOpts); return new OutputAnalyzer(pb.start()); } } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java 2023-10-06 05:33:33.000000000 +0000 @@ -104,7 +104,7 @@ } private void performTest(List opts) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, opts); + ProcessBuilder pb = ProcessTools.createTestJvm(opts); OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println(output.getStdout()); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTableRehashFullGC.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTableRehashFullGC.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTableRehashFullGC.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTableRehashFullGC.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,44 @@ +/* + * 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. + */ + +package gc.g1; + +/* + * @test TestStringDeduplicationTableRehashFullGC + * @summary Test string deduplication table rehash during full GC + * @bug 8310176 + * @key gc + * @requires vm.gc.G1 + * @library /test/lib + * @library / + * @modules java.base/jdk.internal.misc:open + * @modules java.base/java.lang:open + * java.management + * @run main gc.g1.TestStringDeduplicationTableRehashFullGC + */ + +public class TestStringDeduplicationTableRehashFullGC { + public static void main(String[] args) throws Exception { + TestStringDeduplicationTools.testTableRehashFullGC(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTools.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTools.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTools.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/g1/TestStringDeduplicationTools.java 2023-10-06 05:33:33.000000000 +0000 @@ -383,6 +383,23 @@ output.shouldHaveExitValue(0); } + public static void testTableRehashFullGC() throws Exception { + // Test with StringDeduplicationRehashALot using full GCs + // Table resizing prevents table rehashing from happening, thus we use + // SmallNumberOfStrings to limit the number of table resizes. + OutputAnalyzer output = DeduplicationTest.run(SmallNumberOfStrings, + DefaultAgeThreshold, + FullGC, + "-Xlog:gc,gc+stringdedup=trace", + "-XX:+StringDeduplicationRehashALot"); + output.shouldContain("Concurrent String Deduplication"); + output.shouldContain("Deduplicated:"); + output.shouldContain("Full GC"); + output.shouldMatch("Rehash Count: [1-9]"); + output.shouldNotContain("Hash Seed: 0x0"); + output.shouldHaveExitValue(0); + } + public static void testAgeThreshold() throws Exception { OutputAnalyzer output; diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestAllocateHeapAtError.java 2023-10-06 05:33:33.000000000 +0000 @@ -46,8 +46,7 @@ f = new File(test_dir, UUID.randomUUID().toString()); } while(f.exists()); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:AllocateHeapAt=" + f.getName(), "-Xlog:gc+heap=info", "-Xmx32m", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestAllocateHeapAt.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestAllocateHeapAt.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestAllocateHeapAt.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestAllocateHeapAt.java 2023-10-06 05:33:33.000000000 +0000 @@ -40,8 +40,7 @@ public class TestAllocateHeapAt { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:AllocateHeapAt=" + System.getProperty("test.dir", "."), "-Xlog:gc+heap=info", "-Xmx32m", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java 2023-10-06 05:33:33.000000000 +0000 @@ -62,7 +62,7 @@ "-Xlog:gc+heap=info", "-version"}); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, flags); + ProcessBuilder pb = ProcessTools.createTestJvm(flags); OutputAnalyzer output = new OutputAnalyzer(pb.start()); System.out.println("Output:\n" + output.getOutput()); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/TestVerifyDuringStartup.java 2023-10-06 05:33:33.000000000 +0000 @@ -38,8 +38,7 @@ public class TestVerifyDuringStartup { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:-UseTLAB", "-XX:+UnlockDiagnosticVMOptions", "-XX:+VerifyDuringStartup", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/whitebox/TestWBGC.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/whitebox/TestWBGC.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/gc/whitebox/TestWBGC.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/gc/whitebox/TestWBGC.java 2023-10-06 05:33:33.000000000 +0000 @@ -43,8 +43,7 @@ public class TestWBGC { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-Xbootclasspath/a:.", "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/ProblemList.txt openjdk-lts-11.0.21+9/test/hotspot/jtreg/ProblemList.txt --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/ProblemList.txt 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/ProblemList.txt 2023-10-06 05:33:33.000000000 +0000 @@ -40,13 +40,67 @@ # :hotspot_compiler +compiler/aot/DeoptimizationTest.java 8310619 macosx-x64 +compiler/aot/RecompilationTest.java 8310619 macosx-x64 +compiler/aot/SharedUsageTest.java 8310619 macosx-x64 +compiler/aot/TestHeapBase.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeDynamic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeDynamic2CompiledTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeDynamic2InterpretedTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeDynamic2NativeTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeInterface2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeInterface2CompiledTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeInterface2InterpretedTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeInterface2NativeTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeSpecial2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeSpecial2CompiledTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeSpecial2InterpretedTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeSpecial2NativeTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeStatic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeStatic2CompiledTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeStatic2InterpretedTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeStatic2NativeTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeVirtual2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeVirtual2CompiledTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeVirtual2InterpretedTest.java 8310619 macosx-x64 +compiler/aot/calls/fromAot/AotInvokeVirtual2NativeTest.java 8310619 macosx-x64 +compiler/aot/calls/fromCompiled/CompiledInvokeDynamic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromCompiled/CompiledInvokeInterface2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromCompiled/CompiledInvokeSpecial2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromCompiled/CompiledInvokeStatic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromCompiled/CompiledInvokeVirtual2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromInterpreted/InterpretedInvokeDynamic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromInterpreted/InterpretedInvokeInterface2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromInterpreted/InterpretedInvokeSpecial2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromInterpreted/InterpretedInvokeStatic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromInterpreted/InterpretedInvokeVirtual2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromNative/NativeInvokeSpecial2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromNative/NativeInvokeStatic2AotTest.java 8310619 macosx-x64 +compiler/aot/calls/fromNative/NativeInvokeVirtual2AotTest.java 8310619 macosx-x64 +compiler/aot/cli/DisabledAOTWithLibraryTest.java 8310619 macosx-x64 +compiler/aot/cli/MultipleAOTLibraryTest.java 8310619 macosx-x64 +compiler/aot/cli/SingleAOTLibraryTest.java 8310619 macosx-x64 +compiler/aot/cli/SingleAOTOptionTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/AtFileTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/CompileClassTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/CompileClassWithDebugTest.java 8303074,8310619 linux-aarch64,macosx-x64 +compiler/aot/cli/jaotc/CompileDirectoryTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/CompileJarTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/CompileModuleTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/IgnoreErrorsTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/ListOptionTest.java 8310619 macosx-x64 +compiler/aot/cli/jaotc/ListOptionWrongFileTest.java 8310619 macosx-x64 +compiler/aot/fingerprint/SelfChanged.java 8310619 macosx-x64 +compiler/aot/fingerprint/SelfChangedCDS.java 8310619 macosx-x64 +compiler/aot/fingerprint/SuperChanged.java 8310619 macosx-x64 +compiler/aot/verification/ClassAndLibraryNotMatchTest.java 8310619 macosx-x64 compiler/aot/verification/vmflags/TrackedFlagTest.java 8215224 generic-all compiler/aot/verification/vmflags/NotTrackedFlagTest.java 8215224 generic-all -compiler/aot/cli/jaotc/CompileClassWithDebugTest.java 8303074 linux-aarch64 compiler/ciReplay/TestSAServer.java 8029528 generic-all compiler/codecache/stress/OverloadCompileQueueTest.java 8166554 generic-all compiler/codegen/Test6896617.java 8193479 generic-all compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8140405 generic-all +compiler/gcbarriers/UnsafeIntrinsicsTest.java#z 8315528 linux-x64 compiler/jvmci/compilerToVM/GetFlagValueTest.java 8204459 generic-all compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java 8158860 generic-all compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all @@ -65,13 +119,13 @@ compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64,generic-i586 -compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMAbortThreshold.java 8183263,8313877 generic-x64,generic-i586,generic-ppc64le compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java 8183263 generic-x64,generic-i586 compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java 8183263 generic-x64,generic-i586 compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java 8183263 generic-x64,generic-i586 compiler/rtm/locking/TestRTMLockingCalculationDelay.java 8183263 generic-x64,generic-i586 compiler/rtm/locking/TestRTMLockingThreshold.java 8183263 generic-x64,generic-i586 -compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263 generic-x64,generic-i586 +compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263,8313877 generic-x64,generic-i586,generic-ppc64le compiler/rtm/locking/TestUseRTMDeopt.java 8183263 generic-x64,generic-i586 compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64,generic-i586 compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64,generic-i586 @@ -96,11 +150,13 @@ gc/stress/gcbasher/TestGCBasherWithCMS.java 8272195 generic-i586 gc/cms/TestBubbleUpRef.java 8272195 generic-i586 gc/stress/gcold/TestGCOldWithCMS.java 8272195 generic-i586 +gc/stress/gcold/TestGCOldWithZ.java 8315531 linux-x64 ############################################################################# # :hotspot_runtime +runtime/CompressedOops/CompressedClassPointers.java 8305765 generic-all runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all runtime/handshake/HandshakeWalkSuspendExitTest.java 8214174 generic-all runtime/SharedArchiveFile/SASymbolTableTest.java 8193639 solaris-all diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/DumpClassList.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/DumpClassList.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/DumpClassList.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/DumpClassList.java 2023-10-06 05:33:33.000000000 +0000 @@ -76,8 +76,7 @@ String appendJar = JarBuilder.build("bootappend", "boot/append/Foo"); // dump class list - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:DumpLoadedClassList=" + classList, "--patch-module=java.base=" + patchJar, "-Xbootclasspath/a:" + appendJar, diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/GraalWithLimitedMetaspace.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/GraalWithLimitedMetaspace.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/GraalWithLimitedMetaspace.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/GraalWithLimitedMetaspace.java 2023-10-06 05:33:33.000000000 +0000 @@ -86,7 +86,7 @@ } static void dumpLoadedClasses(String[] expectedClasses) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( TestCommon.makeCommandLineForAppCDS( "-XX:DumpLoadedClassList=" + CLASSLIST_FILE, // trigger JVMCI runtime init so that JVMCI classes will be @@ -114,7 +114,7 @@ } static void dumpArchive() throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( TestCommon.makeCommandLineForAppCDS( "-cp", TESTJAR, diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/sharedStrings/SharedStringsBasic.java 2023-10-06 05:33:33.000000000 +0000 @@ -46,7 +46,7 @@ String sharedArchiveConfigFile = TestCommon.getSourceFile("SharedStringsBasic.txt").toString(); - ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder dumpPb = ProcessTools.createTestJvm( TestCommon.makeCommandLineForAppCDS( "-cp", appJar, "-XX:SharedArchiveConfigFile=" + sharedArchiveConfigFile, @@ -58,7 +58,7 @@ .shouldContain("Shared string table stats") .shouldHaveExitValue(0); - ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder runPb = ProcessTools.createTestJvm( TestCommon.makeCommandLineForAppCDS( "-cp", appJar, "-XX:SharedArchiveFile=./SharedStringsBasic.jsa", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/sharedStrings/SysDictCrash.java 2023-10-06 05:33:33.000000000 +0000 @@ -41,7 +41,7 @@ public static void main(String[] args) throws Exception { // SharedBaseAddress=0 puts the archive at a very high address on solaris, // which provokes the crash. - ProcessBuilder dumpPb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder dumpPb = ProcessTools.createTestJvm( TestCommon.makeCommandLineForAppCDS( "-XX:+UseG1GC", "-XX:MaxRAMPercentage=12.5", "-cp", ".", @@ -51,7 +51,7 @@ TestCommon.checkDump(TestCommon.executeAndLog(dumpPb, "dump")); - ProcessBuilder runPb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder runPb = ProcessTools.createTestJvm( TestCommon.makeCommandLineForAppCDS( "-XX:+UseG1GC", "-XX:MaxRAMPercentage=12.5", "-XX:SharedArchiveFile=./SysDictCrash.jsa", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/TestCommon.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/TestCommon.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/appcds/TestCommon.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/appcds/TestCommon.java 2023-10-06 05:33:33.000000000 +0000 @@ -147,7 +147,7 @@ for (String s : opts.suffix) cmd.add(s); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmd); + ProcessBuilder pb = ProcessTools.createTestJvm(cmd); return executeAndLog(pb, "dump"); } @@ -197,7 +197,7 @@ } } - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmd); + ProcessBuilder pb = ProcessTools.createTestJvm(cmd); return executeAndLog(pb, "exec"); } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/BootstrapMethod/BSMCalledTwice.java 2023-10-06 05:33:33.000000000 +0000 @@ -107,7 +107,7 @@ }; cl.loadClass(classTestCName); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", classTestCName); + ProcessBuilder pb = ProcessTools.createTestJvm("-cp", ".", classTestCName); OutputAnalyzer output = new OutputAnalyzer(pb.start()); String test_output = output.getOutput(); if (test_output == null) { diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/ClassFile/UnsupportedClassFileVersion.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/ClassFile/UnsupportedClassFileVersion.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/ClassFile/UnsupportedClassFileVersion.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/ClassFile/UnsupportedClassFileVersion.java 2023-10-06 05:33:33.000000000 +0000 @@ -42,7 +42,7 @@ public class UnsupportedClassFileVersion implements Opcodes { public static void main(String... args) throws Exception { writeClassFile(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", "ClassFile"); + ProcessBuilder pb = ProcessTools.createTestJvm("-cp", ".", "ClassFile"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("ClassFile has been compiled by a more recent version of the " + "Java Runtime (class file version 99.0), this version of " + diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/handshake/HandshakeTransitionTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/handshake/HandshakeTransitionTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/handshake/HandshakeTransitionTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/handshake/HandshakeTransitionTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -53,8 +53,7 @@ useJVMCICompilerStr = "-XX:+UnlockExperimentalVMOptions"; } ProcessBuilder pb = - ProcessTools.createJavaProcessBuilder( - true, + ProcessTools.createTestJvm( "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, "-XX:+SafepointALot", "-XX:GuaranteedSafepointInterval=20", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/modules/ModuleOptionsTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/modules/ModuleOptionsTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/modules/ModuleOptionsTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/modules/ModuleOptionsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,6 +28,7 @@ * options but accumulates --add-module values. * @modules java.base/jdk.internal.misc * @library /test/lib + * @run driver ModuleOptionsTest */ import jdk.test.lib.process.OutputAnalyzer; diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleClassList.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleClassList.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleClassList.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/modules/PatchModule/PatchModuleClassList.java 2023-10-06 05:33:33.000000000 +0000 @@ -63,8 +63,7 @@ String moduleJar = BasicJarBuilder.getTestJar("javanaming.jar"); String classList = "javanaming.list"; - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:DumpLoadedClassList=" + classList, "--patch-module=java.naming=" + moduleJar, "PatchModuleMain", BOOT_CLASS.replace('/', '.')); @@ -98,8 +97,7 @@ moduleJar = BasicJarBuilder.getTestJar("javasql.jar"); classList = "javasql.list"; - pb = ProcessTools.createJavaProcessBuilder( - true, + pb = ProcessTools.createTestJvm( "-XX:DumpLoadedClassList=" + classList, "--patch-module=java.sql=" + moduleJar, "PatchModuleMain", PLATFORM_CLASS.replace('/', '.')); @@ -131,8 +129,7 @@ moduleJar = BasicJarBuilder.getTestJar("hello.jar"); classList = "hello.list"; - pb = ProcessTools.createJavaProcessBuilder( - true, + pb = ProcessTools.createTestJvm( "-XX:DumpLoadedClassList=" + classList, "-Xbootclasspath/a:" + moduleJar, "Hello"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/os/AvailableProcessors.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/os/AvailableProcessors.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/os/AvailableProcessors.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/os/AvailableProcessors.java 2023-10-06 05:33:33.000000000 +0000 @@ -68,8 +68,7 @@ // Get the java command we want to execute // Enable logging for easier failure diagnosis ProcessBuilder master = - ProcessTools.createJavaProcessBuilder(false, - "-Xlog:os=trace", + ProcessTools.createJavaProcessBuilder("-Xlog:os=trace", "AvailableProcessors"); int[] expected = new int[] { 1, available/2, available-1, available }; diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/os/TestUseCpuAllocPath.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/os/TestUseCpuAllocPath.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/os/TestUseCpuAllocPath.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/os/TestUseCpuAllocPath.java 2023-10-06 05:33:33.000000000 +0000 @@ -41,8 +41,7 @@ public static void main(String[] args) throws Exception { ProcessBuilder pb = - ProcessTools.createJavaProcessBuilder(false, - "-Xlog:os=trace", + ProcessTools.createJavaProcessBuilder("-Xlog:os=trace", "-XX:+UnlockDiagnosticVMOptions", "-XX:+UseCpuAllocPath", "-version"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/SharedArchiveFile/SharedArchiveFile.java 2023-10-06 05:33:33.000000000 +0000 @@ -41,20 +41,20 @@ // methods to form command line to create/use shared archive. public class SharedArchiveFile { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-Xshare:dump"); OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile"); CDSTestUtils.checkDump(out); // -XX:+DumpSharedSpaces should behave the same as -Xshare:dump - pb = ProcessTools.createJavaProcessBuilder(true, + pb = ProcessTools.createTestJvm( "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-XX:+DumpSharedSpaces"); out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile"); CDSTestUtils.checkDump(out); - pb = ProcessTools.createJavaProcessBuilder(true, + pb = ProcessTools.createTestJvm( "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-Xshare:on", "-version"); out = CDSTestUtils.executeAndLog(pb, "SharedArchiveFile"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/StackTrace/LargeClassTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/StackTrace/LargeClassTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/StackTrace/LargeClassTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/StackTrace/LargeClassTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -46,7 +46,7 @@ public class LargeClassTest implements Opcodes { public static void main(String... args) throws Exception { writeClassFile(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", "Large"); + ProcessBuilder pb = ProcessTools.createTestJvm("-cp", ".", "Large"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/Unsafe/RangeCheck.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/Unsafe/RangeCheck.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/Unsafe/RangeCheck.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/Unsafe/RangeCheck.java 2023-10-06 05:33:33.000000000 +0000 @@ -44,8 +44,7 @@ return; } - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-Xmx128m", "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", "-XX:-TransmitErrorReport", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/verifier/OverriderMsg.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/verifier/OverriderMsg.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/verifier/OverriderMsg.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/verifier/OverriderMsg.java 2023-10-06 05:33:33.000000000 +0000 @@ -125,7 +125,7 @@ public static void main(String... args) throws Exception { dump_HasFinal(); dump_Overrider(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", "Overrider"); + ProcessBuilder pb = ProcessTools.createTestJvm("-cp", ".", "Overrider"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain( "java.lang.VerifyError: class Overrider overrides final method HasFinal.m(Ljava/lang/String;)V"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/verifier/TestANewArray.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/verifier/TestANewArray.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/verifier/TestANewArray.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/verifier/TestANewArray.java 2023-10-06 05:33:33.000000000 +0000 @@ -69,7 +69,7 @@ byte[] classFile_254 = dumpClassFile(cfv, test_Dimension_254, array_Dimension_254); writeClassFileFromByteArray(classFile_254); System.err.println("Running with cfv: " + cfv + ", test_Dimension_254"); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); + ProcessBuilder pb = ProcessTools.createTestJvm("-verify", "-cp", ".", classCName); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotContain("java.lang.VerifyError"); output.shouldHaveExitValue(0); @@ -78,7 +78,7 @@ byte[] classFile_255 = dumpClassFile(cfv, test_Dimension_255, array_Dimension_255); writeClassFileFromByteArray(classFile_255); System.err.println("Running with cfv: " + cfv + ", test_Dimension_255"); - pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); + pb = ProcessTools.createTestJvm("-verify", "-cp", ".", classCName); output = new OutputAnalyzer(pb.start()); // If anewarray has an operand with 255 array dimensions then VerifyError should // be thrown because the resulting array would have 256 dimensions. @@ -95,7 +95,7 @@ byte[] classFile_264 = dumpClassFile(cfv, test_Dimension_264, array_Dimension_264); writeClassFileFromByteArray(classFile_264); System.err.println("Running with cfv: " + cfv + ", test_Dimension_264"); - pb = ProcessTools.createJavaProcessBuilder(true, "-verify", "-cp", ".", classCName); + pb = ProcessTools.createTestJvm("-verify", "-cp", ".", classCName); output = new OutputAnalyzer(pb.start()); output.shouldContain("java.lang.ClassFormatError"); output.shouldHaveExitValue(1); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/verifier/TestMultiANewArray.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/verifier/TestMultiANewArray.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/runtime/verifier/TestMultiANewArray.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/runtime/verifier/TestMultiANewArray.java 2023-10-06 05:33:33.000000000 +0000 @@ -48,7 +48,7 @@ int cfv = Integer.parseInt(args[0]); writeClassFile(cfv); System.err.println("Running with cfv: " + cfv); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-cp", ".", "ClassFile"); + ProcessBuilder pb = ProcessTools.createTestJvm("-cp", ".", "ClassFile"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("VerifyError"); output.shouldHaveExitValue(1); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/sanity/MismatchedWhiteBox/WhiteBox.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/sanity/MismatchedWhiteBox/WhiteBox.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/sanity/MismatchedWhiteBox/WhiteBox.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/sanity/MismatchedWhiteBox/WhiteBox.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, 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 @@ -36,6 +36,15 @@ package sun.hotspot; public class WhiteBox { + @SuppressWarnings("serial") + public static class WhiteBoxPermission extends java.security.BasicPermission { + // ClassFileInstaller is hard-coded to copy WhiteBox$WhiteBoxPermission, so let's + // make a fake one here as well. + public WhiteBoxPermission(String s) { + super(s); + } + } + private static native void registerNatives(); static { registerNatives(); } public native int notExistedMethod(); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeClass.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeClass.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeClass.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeClass.java 2023-10-06 05:33:33.000000000 +0000 @@ -50,7 +50,7 @@ pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", "agent.jar", "GetObjectSizeClassAgent.class"}); pb.start().waitFor(); - ProcessBuilder pt = ProcessTools.createJavaProcessBuilder(true, "-javaagent:agent.jar", "GetObjectSizeClassAgent"); + ProcessBuilder pt = ProcessTools.createTestJvm("-javaagent:agent.jar", "GetObjectSizeClassAgent"); OutputAnalyzer output = new OutputAnalyzer(pt.start()); output.stdoutShouldContain("GetObjectSizeClass passed"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeOverflow.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeOverflow.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeOverflow.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/jvmti/GetObjectSizeOverflow.java 2023-10-06 05:33:33.000000000 +0000 @@ -57,7 +57,7 @@ pb.command(new String[] { JDKToolFinder.getJDKTool("jar"), "cmf", "MANIFEST.MF", "agent.jar", "GetObjectSizeOverflowAgent.class"}); pb.start().waitFor(); - ProcessBuilder pt = ProcessTools.createJavaProcessBuilder(true, "-Xmx4000m", "-javaagent:agent.jar", "GetObjectSizeOverflowAgent"); + ProcessBuilder pt = ProcessTools.createTestJvm("-Xmx4000m", "-javaagent:agent.jar", "GetObjectSizeOverflowAgent"); OutputAnalyzer output = new OutputAnalyzer(pt.start()); if (output.getStdout().contains("Could not reserve enough space") || output.getStderr().contains("java.lang.OutOfMemoryError")) { diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/logging/TestLogRotation.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/logging/TestLogRotation.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/logging/TestLogRotation.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/logging/TestLogRotation.java 2023-10-06 05:33:33.000000000 +0000 @@ -72,8 +72,7 @@ public static void runTest(int numberOfFiles) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-cp", System.getProperty("java.class.path"), "-Xlog:gc=debug:" + logFileName + "::filesize=" + logFileSizeK + "k" diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSCore.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSCore.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSCore.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSCore.java 2023-10-06 05:33:33.000000000 +0000 @@ -95,7 +95,7 @@ List options = new ArrayList<>(); options.addAll(Arrays.asList(jArgs)); crashOut = - ProcessTools.executeProcess(getTestJavaCommandlineWithPrefix( + ProcessTools.executeProcess(getTestJvmCommandlineWithPrefix( RUN_SHELL_NO_LIMIT, options.toArray(new String[0]))); } catch (Throwable t) { throw new Error("Can't execute the java cds process.", t); @@ -258,9 +258,9 @@ return null; } - private static String[] getTestJavaCommandlineWithPrefix(String prefix, String... args) { + private static String[] getTestJvmCommandlineWithPrefix(String prefix, String... args) { try { - String cmd = ProcessTools.getCommandLine(ProcessTools.createJavaProcessBuilder(true, args)); + String cmd = ProcessTools.getCommandLine(ProcessTools.createTestJvm(args)); return new String[]{"sh", "-c", prefix + cmd}; } catch (Throwable t) { throw new Error("Can't create process builder: " + t, t); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/sa/ClhsdbFlags.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/sa/ClhsdbFlags.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/sa/ClhsdbFlags.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/sa/ClhsdbFlags.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -33,6 +33,7 @@ /** * @test * @bug 8190198 + * @bug 8217612 * @summary Test clhsdb flags command * @requires vm.hasSA * @library /test/lib @@ -41,8 +42,8 @@ public class ClhsdbFlags { - public static void main(String[] args) throws Exception { - System.out.println("Starting ClhsdbFlags test"); + public static void runBasicTest() throws Exception { + System.out.println("Starting ClhsdbFlags basic test"); LingeredApp theApp = null; try { @@ -90,4 +91,54 @@ } System.out.println("Test PASSED"); } + + public static void runAllTypesTest() throws Exception { + System.out.println("Starting ClhsdbFlags all types test"); + + LingeredApp theApp = null; + try { + ClhsdbLauncher test = new ClhsdbLauncher(); + List vmArgs = new ArrayList(); + vmArgs.add("-XX:+UnlockDiagnosticVMOptions"); // bool + vmArgs.add("-XX:ActiveProcessorCount=1"); // int + vmArgs.add("-XX:ParallelGCThreads=1"); // uint + vmArgs.add("-XX:MaxJavaStackTraceDepth=1024"); // intx + vmArgs.add("-XX:LogEventsBufferEntries=10"); // uintx + vmArgs.add("-XX:HeapSizePerGCThread=32m"); // size_t + vmArgs.add("-XX:NativeMemoryTracking=off"); // ccstr + vmArgs.add("-XX:OnError='echo error'"); // ccstrlist + vmArgs.add("-XX:CompileThresholdScaling=1.0"); // double + vmArgs.add("-XX:ErrorLogTimeout=120"); // uint64_t + vmArgs.addAll(Utils.getVmOptions()); + theApp = LingeredApp.startApp(vmArgs); + System.out.println("Started LingeredApp with pid " + theApp.getPid()); + + List cmds = List.of("flags"); + + Map> expStrMap = new HashMap<>(); + expStrMap.put("flags", List.of( + "UnlockDiagnosticVMOptions = true", + "ActiveProcessorCount = 1", + "ParallelGCThreads = 1", + "MaxJavaStackTraceDepth = 1024", + "LogEventsBufferEntries = 10", + "HeapSizePerGCThread = 3", + "NativeMemoryTracking = \"off\"", + "OnError = \"'echo error'\"", + "CompileThresholdScaling = 1.0", + "ErrorLogTimeout = 120")); + + test.run(theApp.getPid(), cmds, expStrMap, null); + } catch (Exception ex) { + throw new RuntimeException("Test ERROR " + ex, ex); + } finally { + LingeredApp.stopApp(theApp); + } + System.out.println("Test PASSED"); + } + + public static void main(String[] args) throws Exception { + runBasicTest(); + runAllTypesTest(); + } } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/serviceability/sa/TestJmapCore.java 2023-10-06 05:33:33.000000000 +0000 @@ -86,7 +86,7 @@ } static void test(String type) throws Throwable { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-XX:+CreateCoredumpOnCrash", + ProcessBuilder pb = ProcessTools.createTestJvm("-XX:+CreateCoredumpOnCrash", "-Xmx512m", "-XX:MaxMetaspaceSize=64m", "-XX:+CrashOnOutOfMemoryError", "-XX:-TransmitErrorReport", TestJmapCore.class.getName(), type); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java 2023-10-06 05:33:33.000000000 +0000 @@ -174,9 +174,7 @@ while (!done) { String[] cmd = cmd(classStart, classStop); try { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - /* addTestVmAndJavaOptions = */ true, - cmd); + ProcessBuilder pb = ProcessTools.createTestJvm(cmd); String commandLine = pb.command() .stream() .collect(Collectors.joining(" ")); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java 2023-10-06 05:33:33.000000000 +0000 @@ -47,7 +47,7 @@ } OutputAnalyzer oa; try { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args); + ProcessBuilder pb = ProcessTools.createTestJvm(args); oa = new OutputAnalyzer(pb.start()); } catch (Exception e) { throw new Error("Unexpected exception on test jvm start :" + e, e); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/testlibrary_tests/ctw/CtwTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/testlibrary_tests/ctw/CtwTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/testlibrary_tests/ctw/CtwTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/testlibrary_tests/ctw/CtwTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -102,7 +102,7 @@ } } } - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmd); + ProcessBuilder pb = ProcessTools.createTestJvm(cmd); OutputAnalyzer output = new OutputAnalyzer(pb.start()); dump(output, "compile"); output.shouldHaveExitValue(0); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/gc/huge/quicklook/largeheap/MemOptions/MemOptionsTest.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/gc/huge/quicklook/largeheap/MemOptions/MemOptionsTest.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/gc/huge/quicklook/largeheap/MemOptions/MemOptionsTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/gc/huge/quicklook/largeheap/MemOptions/MemOptionsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -94,7 +94,7 @@ var cmd = new ArrayList(); Collections.addAll(cmd, opts); cmd.add(MemStat.class.getName()); - var pb = ProcessTools.createJavaProcessBuilder(true, cmd); + var pb = ProcessTools.createTestJvm(cmd); var output = new OutputAnalyzer(pb.start()); if (output.getExitValue() != 0) { output.reportDiagnosticSummary(); @@ -107,7 +107,7 @@ var cmd = new ArrayList(); Collections.addAll(cmd, opts); cmd.add(MemStat.class.getName()); - var pb = ProcessTools.createJavaProcessBuilder(true, cmd); + var pb = ProcessTools.createTestJvm(cmd); var output = new OutputAnalyzer(pb.start()); if (output.getExitValue() == 0) { output.reportDiagnosticSummary(); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/jit/tiered/Test.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/jit/tiered/Test.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/jit/tiered/Test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/jit/tiered/Test.java 2023-10-06 05:33:33.000000000 +0000 @@ -51,7 +51,7 @@ public static void main(String[] args) throws Exception { { System.out.println("TieredCompilation is enabled"); - var pb = ProcessTools.createJavaProcessBuilder(true, + var pb = ProcessTools.createTestJvm( "-XX:+TieredCompilation", "-XX:+PrintTieredEvents", "-version"); @@ -64,7 +64,7 @@ } { System.out.println("TieredCompilation is disabled"); - var pb = ProcessTools.createJavaProcessBuilder(true, + var pb = ProcessTools.createTestJvm( "-XX:-TieredCompilation", "-XX:+PrintTieredEvents", "-version"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/metaspace/flags/maxMetaspaceSize/TestMaxMetaspaceSize.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/metaspace/flags/maxMetaspaceSize/TestMaxMetaspaceSize.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/metaspace/flags/maxMetaspaceSize/TestMaxMetaspaceSize.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/metaspace/flags/maxMetaspaceSize/TestMaxMetaspaceSize.java 2023-10-06 05:33:33.000000000 +0000 @@ -39,8 +39,8 @@ public class TestMaxMetaspaceSize { public static void main(String[] args) throws Exception { ProcessBuilder pb = - ProcessTools.createJavaProcessBuilder(true, "-XX:MaxMetaspaceSize=100m", - maxMetaspaceSize.class.getName()); + ProcessTools.createTestJvm("-XX:MaxMetaspaceSize=100m", + maxMetaspaceSize.class.getName()); OutputAnalyzer out = new OutputAnalyzer(pb.start()); if (out.getExitValue() == 0) { diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat001/thrstat001.cpp openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat001/thrstat001.cpp --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat001/thrstat001.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat001/thrstat001.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -39,177 +39,87 @@ static jvmtiCapabilities caps; static jvmtiEventCallbacks callbacks; static jrawMonitorID access_lock; +static jrawMonitorID wait_lock; static jint result = PASSED; -static jboolean printdump = JNI_FALSE; static jthread thr_ptr = NULL; + static jint state[] = { JVMTI_THREAD_STATE_RUNNABLE, JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER, JVMTI_THREAD_STATE_IN_OBJECT_WAIT }; -static int entry_count = 0; -static int entry_error_count = 0; -static int exit_count = 0; -static int exit_error_count = 0; - -void JNICALL VMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr) { - jvmtiError err; - - err = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_THREAD_START, NULL); +static void +lock(const char* func_name, jrawMonitorID lock) { + jvmtiError err = jvmti->RawMonitorEnter(lock); if (err != JVMTI_ERROR_NONE) { - printf("Failed to enable THREAD_START event: %s (%d)\n", - TranslateError(err), err); + printf("%s: unexpected error in RawMonitorEnter: %s (%d)\n", + func_name, TranslateError(err), err); result = STATUS_FAILED; } - - if (caps.can_generate_method_entry_events) { - err = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_METHOD_ENTRY, NULL); - if (err != JVMTI_ERROR_NONE) { - printf("Failed to enable METHOD_ENTRY event: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - } - - if (caps.can_generate_method_exit_events) { - err = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_METHOD_EXIT, NULL); - if (err != JVMTI_ERROR_NONE) { - printf("Failed to enable METHOD_EXIT event: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - } } -void JNICALL -ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) { - jvmtiError err; - jvmtiThreadInfo thrInfo; - - err = jvmti_env->RawMonitorEnter(access_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorEnter#TS) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - - err = jvmti_env->GetThreadInfo(thread, &thrInfo); +static void +unlock(const char* func_name, jrawMonitorID lock) { + jvmtiError err = jvmti->RawMonitorExit(lock); if (err != JVMTI_ERROR_NONE) { - printf("(GetThreadInfo#TS) unexpected error: %s (%d)\n", - TranslateError(err), err); + printf("%s: unexpected error in RawMonitorExit: %s (%d)\n", + func_name, TranslateError(err), err); result = STATUS_FAILED; } - if (thrInfo.name != NULL && strcmp(thrInfo.name, "thr1") == 0) { - thr_ptr = env->NewGlobalRef(thread); - if (printdump == JNI_TRUE) { - printf(">>> ThreadStart: \"%s\", 0x%p\n", thrInfo.name, thr_ptr); - } - } +} - err = jvmti_env->RawMonitorExit(access_lock); +static void +wait(const char* func_name, jrawMonitorID lock, jint millis) { + jvmtiError err = jvmti->RawMonitorWait(lock, (jlong)millis); if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorExit#TS) unexpected error: %s (%d)\n", - TranslateError(err), err); + printf("%s: unexpected error in RawMonitorWait: %s (%d)\n", + func_name, TranslateError(err), err); result = STATUS_FAILED; } } -void JNICALL MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env, - jthread thread, jmethodID mid) { - jvmtiError err; - jvmtiThreadInfo thrInfo; - jint thrState; - - err = jvmti_env->RawMonitorEnter(access_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorEnter#ME) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } +static void +set_notification_mode(const char* event_name, + jvmtiEventMode mode, + jvmtiEvent event_type, + jthread event_thread) { + const char* action = (mode == JVMTI_ENABLE) ? "enable" : "disable"; + jvmtiError err = jvmti->SetEventNotificationMode(mode, event_type, event_thread); - entry_count++; - err = jvmti_env->GetThreadState(thread, &thrState); if (err != JVMTI_ERROR_NONE) { - printf("(GetThreadState#ME) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - if ((thrState & JVMTI_THREAD_STATE_RUNNABLE) == 0) { - if (entry_error_count == 0) { - err = jvmti_env->GetThreadInfo(thread, &thrInfo); - if (err != JVMTI_ERROR_NONE) { - printf("(GetThreadInfo#ME) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - printf("Wrong thread \"%s\" state on MethodEntry event:\n", - thrInfo.name); - printf(" expected: JVMTI_THREAD_STATE_RUNNABLE\n"); - printf(" got: %s (%d)\n", - TranslateState(thrState), thrState); - } - entry_error_count++; - result = STATUS_FAILED; - } - - err = jvmti_env->RawMonitorExit(access_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorExit#ME) unexpected error: %s (%d)\n", - TranslateError(err), err); + printf("Failed to %s %s event: %s (%d)\n", + action, event_name, TranslateError(err), err); result = STATUS_FAILED; } +} +void JNICALL VMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr) { + set_notification_mode("JVMTI_EVENT_THREAD_START", JVMTI_ENABLE, + JVMTI_EVENT_THREAD_START, NULL); } -void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, - jthread thread, jmethodID mid, - jboolean was_poped_by_exception, jvalue return_value) { +void JNICALL +ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) { jvmtiError err; jvmtiThreadInfo thrInfo; - jint thrState; - err = jvmti_env->RawMonitorEnter(access_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorEnter#MX) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + lock("ThreadStart", access_lock); - exit_count++; - err = jvmti_env->GetThreadState(thread, &thrState); + err = jvmti_env->GetThreadInfo(thread, &thrInfo); if (err != JVMTI_ERROR_NONE) { - printf("(GetThreadState#MX) unexpected error: %s (%d)\n", - TranslateError(err), err); + printf("(GetThreadInfo#TS) unexpected error: %s (%d)\n", + TranslateError(err), err); result = STATUS_FAILED; } - if ((thrState & JVMTI_THREAD_STATE_RUNNABLE) == 0) { - if (exit_error_count == 0) { - err = jvmti_env->GetThreadInfo(thread, &thrInfo); - if (err != JVMTI_ERROR_NONE) { - printf("(GetThreadInfo#MX) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - printf("Wrong thread \"%s\" state on MethodExit event:\n", - thrInfo.name); - printf(" expected: JVMTI_THREAD_STATE_RUNNABLE\n"); - printf(" got: %s (%d)\n", - TranslateState(thrState), thrState); - } - exit_error_count++; - result = STATUS_FAILED; + if (thrInfo.name != NULL && strcmp(thrInfo.name, "thr1") == 0) { + thr_ptr = env->NewGlobalRef(thread); + printf(">>> ThreadStart: \"%s\", 0x%p\n", thrInfo.name, thr_ptr); + set_notification_mode("JVMTI_EVENT_THREAD_START", JVMTI_DISABLE, + JVMTI_EVENT_THREAD_START, NULL); } - err = jvmti_env->RawMonitorExit(access_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorExit#MX) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + unlock("ThreadStart", access_lock); } #ifdef STATIC_BUILD @@ -223,13 +133,12 @@ return JNI_VERSION_1_8; } #endif + jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { jint res; jvmtiError err; - if (options != NULL && strcmp(options, "printdump") == 0) { - printdump = JNI_TRUE; - } + printf("Agent_Initialize started\n"); res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1); if (res != JNI_OK || jvmti == NULL) { @@ -260,23 +169,20 @@ err = jvmti->CreateRawMonitor("_access_lock", &access_lock); if (err != JVMTI_ERROR_NONE) { - printf("(CreateRawMonitor) unexpected error: %s (%d)\n", + printf("(CreateRawMonitor)#access_lock unexpected error: %s (%d)\n", + TranslateError(err), err); + return JNI_ERR; + } + + err = jvmti->CreateRawMonitor("_wait_lock", &wait_lock); + if (err != JVMTI_ERROR_NONE) { + printf("(CreateRawMonitor#wait_lock) unexpected error: %s (%d)\n", TranslateError(err), err); return JNI_ERR; } callbacks.VMInit = &VMInit; callbacks.ThreadStart = &ThreadStart; - if (caps.can_generate_method_entry_events) { - callbacks.MethodEntry = &MethodEntry; - } else { - printf("Warning: MethodEntry event is not implemented\n"); - } - if (caps.can_generate_method_exit_events) { - callbacks.MethodExit = &MethodExit; - } else { - printf("Warning: MethodExit event is not implemented\n"); - } err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); if (err != JVMTI_ERROR_NONE) { printf("(SetEventCallbacks) unexpected error: %s (%d)\n", @@ -284,14 +190,10 @@ return JNI_ERR; } - err = jvmti->SetEventNotificationMode(JVMTI_ENABLE, - JVMTI_EVENT_VM_INIT, NULL); - if (err != JVMTI_ERROR_NONE) { - printf("Failed to enable VM_INIT event: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + set_notification_mode("JVMTI_EVENT_VM_INIT", JVMTI_ENABLE, + JVMTI_EVENT_VM_INIT, NULL); + printf("Agent_Initialize finished\n\n"); return JNI_OK; } @@ -299,10 +201,10 @@ Java_nsk_jvmti_GetThreadState_thrstat001_checkStatus(JNIEnv *env, jclass cls, jint statInd) { jvmtiError err; - jrawMonitorID wait_lock; jint thrState; jint millis; + printf("native method checkStatus started\n"); if (jvmti == NULL) { printf("JVMTI client was not properly loaded!\n"); result = STATUS_FAILED; @@ -316,12 +218,6 @@ } /* wait until thread gets an expected state */ - err = jvmti->CreateRawMonitor("_wait_lock", &wait_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(CreateRawMonitor) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } for (millis = WAIT_START; millis < WAIT_TIME; millis <<= 1) { err = jvmti->GetThreadState(thr_ptr, &thrState); if (err != JVMTI_ERROR_NONE) { @@ -332,36 +228,13 @@ if ((thrState & state[statInd]) != 0) { break; } - err = jvmti->RawMonitorEnter(wait_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorEnter) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - err = jvmti->RawMonitorWait(wait_lock, (jlong)millis); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorWait) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - err = jvmti->RawMonitorExit(wait_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(RawMonitorExit) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - } - err = jvmti->DestroyRawMonitor(wait_lock); - if (err != JVMTI_ERROR_NONE) { - printf("(DestroyRawMonitor) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; + lock("checkStatus", wait_lock); + wait("checkStatus", wait_lock, millis); + unlock("checkStatus", wait_lock); } - if (printdump == JNI_TRUE) { - printf(">>> thread \"thr1\" (0x%p) state: %s (%d)\n", + printf(">>> thread \"thr1\" (0x%p) state: %s (%d)\n", thr_ptr, TranslateState(thrState), thrState); - } if ((thrState & state[statInd]) == 0) { printf("Wrong thread \"thr1\" (0x%p) state:\n", thr_ptr); @@ -371,55 +244,12 @@ TranslateState(thrState), thrState); result = STATUS_FAILED; } + printf("native method checkStatus finished\n\n"); } JNIEXPORT jint JNICALL Java_nsk_jvmti_GetThreadState_thrstat001_getRes(JNIEnv *env, jclass cls) { - jvmtiError err; - - err = jvmti->SetEventNotificationMode(JVMTI_DISABLE, - JVMTI_EVENT_THREAD_START, NULL); - if (err != JVMTI_ERROR_NONE) { - printf("Failed to disable THREAD_START event: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - - if (caps.can_generate_method_entry_events) { - err = jvmti->SetEventNotificationMode(JVMTI_DISABLE, - JVMTI_EVENT_METHOD_ENTRY, NULL); - if (err != JVMTI_ERROR_NONE) { - printf("Failed to disable METHOD_ENTRY event: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - } - - if (caps.can_generate_method_exit_events) { - err = jvmti->SetEventNotificationMode(JVMTI_DISABLE, - JVMTI_EVENT_METHOD_EXIT, NULL); - if (err != JVMTI_ERROR_NONE) { - printf("Failed to disable METHOD_EXIT event: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } - } - - if (printdump == JNI_TRUE) { - printf(">>> total number of method entry events = %d\n", entry_count); - printf(">>> total number of method exit events = %d\n", exit_count); - } - - if (entry_error_count != 0) { - printf("Total number of errors on METHOD_ENTRY: %d of %d events\n", - entry_error_count, entry_count); - } - - if (exit_error_count != 0) { - printf("Total number of errors on METHOD_EXIT: %d of %d events\n", - exit_error_count, exit_count); - } - + printf("native method getRes: result: %d\n\n", result); return result; } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RetransformClasses/retransform003/TestDriver.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RetransformClasses/retransform003/TestDriver.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RetransformClasses/retransform003/TestDriver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RetransformClasses/retransform003/TestDriver.java 2023-10-06 05:33:33.000000000 +0000 @@ -69,8 +69,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-agentlib:retransform003-01=id=1 can_retransform_classes=1", "-agentlib:retransform003-02=id=2 can_retransform_classes=0", "-agentlib:retransform003-03=id=3 can_retransform_classes=1", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix001/TestDescription.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix001/TestDescription.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix001/TestDescription.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix001/TestDescription.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -47,7 +47,7 @@ * /test/lib * @run driver jdk.test.lib.FileInstaller . . * @run main/othervm/native - * -agentlib:SetNativeMethodPrefix001= + * -agentlib:SetNativeMethodPrefix001 * nsk.jvmti.SetNativeMethodPrefix.SetNativeMethodPrefix001 */ diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix002/TestDriver.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix002/TestDriver.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix002/TestDriver.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetNativeMethodPrefix/SetNativeMethodPrefix002/TestDriver.java 2023-10-06 05:33:33.000000000 +0000 @@ -58,8 +58,7 @@ public class TestDriver { public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-agentlib:SetNativeMethodPrefix001=trace=all", "-agentlib:SetNativeMethodPrefix002-01=trace=all prefix=wa_", "-agentlib:SetNativeMethodPrefix002-02=trace=all prefix=wb_", diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -48,7 +48,6 @@ #define NSK_JVMTI_MAX_OPTIONS 10 #define NSK_JVMTI_OPTION_START '-' -#define NSK_JVMTI_OPTION_VAL_SEP '=' #define NSK_JVMTI_OPT_PATH_TO_NEW_BYTE_CODE "pathToNewByteCode" #define PATH_FORMAT "%s%02d/%s" @@ -191,23 +190,29 @@ } } -int isOptSep(char c) { - return isspace(c) || c == '~'; -} - - -/** - * - * The current option will not perform more than one - * single option which given, this is due to places explained - * in this question. - * - **/ +/* + * Tokenize a string based on a list of delimiters. + */ +static char* token(char **s, const char *delim) { + char *p; + char *start = *s; + + if (s == NULL || *s == NULL) { + return NULL; + } + + p = strpbrk(*s, delim); + if (p != NULL) { + /* Advance to next token. */ + *p = '\0'; + *s = p + 1; + } else { + /* End of tokens. */ + *s = NULL; + } - /* - * This whole play can be reduced with simple StringTokenizer (strtok). - * - */ + return start; +} #if !defined(__clang_major__) && defined(__GNUC__) && (__GNUC__ >= 8) _Pragma("GCC diagnostic push") @@ -215,82 +220,41 @@ #endif int nsk_jvmti_parseOptions(const char options[]) { - size_t len; - const char* opt; int success = NSK_TRUE; - context.options.string = NULL; - context.options.count = 0; - context.waittime = 2; - + char *str = NULL; + char *name = NULL; + char *value = NULL; + const char *delimiters = " ,~"; if (options == NULL) - return NSK_TRUE; - - len = strlen(options); - context.options.string = (char*)malloc(len + 2); + return success; - if (context.options.string == NULL) { - nsk_complain("nsk_jvmti_parseOptions(): out of memory\n"); - return NSK_FALSE; - } - strncpy(context.options.string, options, len); - context.options.string[len] = '\0'; - context.options.string[len+1] = '\0'; - - for (opt = context.options.string; ; ) { - const char* opt_end; - const char* val_sep; - int opt_len=0; - int val_len=0; - int exit=1; - - while (*opt != '\0' && isOptSep(*opt)) opt++; - if (*opt == '\0') break; - - val_sep = NULL; - /* - This should break when the first option it encounters other wise - */ - for (opt_end = opt, opt_len=0; !(*opt_end == '\0' || isOptSep(*opt_end)); opt_end++,opt_len++) { - if (*opt_end == NSK_JVMTI_OPTION_VAL_SEP) { - val_sep = opt_end; - exit=0; - break; - } - } - - if (exit == 1) break; + /* + * Save a copy of the full options string for + * ArgumentHandler.getAgentOptionsString(). + */ + context.options.string = strdup(options); + + /* Create a temporary copy of the options string to be tokenized. */ + str = strdup(options); + while ((name = token(&str, delimiters)) != NULL) { + value = strchr(name, '='); - /* now scan for the search for the option value end. - - */ - exit =1; - opt_end++; - val_sep++; - /** - * I was expecting this jvmti_parseOptions(), - * should be for multiple options as well. - * If this break is not there then It will expects - * to have. so a space should be sufficient as well. - */ - for(val_len=0; !(*opt_end == '\0' || isOptSep(*opt_end)); opt_end++,val_len++) { - //if (*opt_end == NSK_JVMTI_OPTION_START) { - // break; - //} + if (value != NULL) { + *value++ = '\0'; } - - if (!add_option(opt, opt_len, val_sep, val_len)) { + if (!add_option(name, (int)strlen(name), value, + value ? (int)strlen(value) : 0)) { success = NSK_FALSE; break; } - opt_end++; - opt = opt_end; } - if (!success) { nsk_jvmti_free(); } - + if (str != NULL) { + free(str); + } return success; } diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfo/Test.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfo/Test.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfo/Test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfo/Test.java 2023-10-06 05:33:33.000000000 +0000 @@ -53,7 +53,7 @@ public static void main(String[] args) throws Exception { { System.out.println("SegmentedCodeCache is enabled"); - var pb = ProcessTools.createJavaProcessBuilder(true, + var pb = ProcessTools.createTestJvm( "-XX:+SegmentedCodeCache", "-XX:+PrintCodeCache", "-version"); @@ -63,7 +63,7 @@ } { System.out.println("SegmentedCodeCache is disabled"); - var pb = ProcessTools.createJavaProcessBuilder(true, + var pb = ProcessTools.createTestJvm( "-XX:-SegmentedCodeCache", "-XX:+PrintCodeCache", "-version"); diff -Nru openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfoOnCompilation/Test.java openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfoOnCompilation/Test.java --- openjdk-lts-11.0.20.1+1/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfoOnCompilation/Test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/hotspot/jtreg/vmTestbase/vm/compiler/CodeCacheInfoOnCompilation/Test.java 2023-10-06 05:33:33.000000000 +0000 @@ -46,7 +46,7 @@ private static String REGEXP = "^(CodeCache|(CodeHeap.*)): size=\\d+Kb used=\\d+Kb max_used=\\d+Kb free=\\d+Kb"; public static void main(String[] args) throws Exception { - var pb = ProcessTools.createJavaProcessBuilder(true, + var pb = ProcessTools.createTestJvm( "-XX:-PrintCodeCache", "-XX:+PrintCodeCacheOnCompilation", "-XX:-Inline", diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.html openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.html --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.html 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.html 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,12 @@ + + + + + + + +
          + +
          + + diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xml 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,4 @@ + + + 𠮟 + diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest1.xsl 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,26 @@ + + + + + + + + + + +
          + + + + + + + +
          +
          + + +
          +
          diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.txt 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,4 @@ +root@attr:null +tag1@attr:𠮟 +tag2@attr:𠀋 +tag3@attr:𣱿 diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest2.xml 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,6 @@ + + + + + + diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest.java openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest.java --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/transform/SurrogateTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * 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. + */ + +package transform; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import static jaxp.library.JAXPTestUtilities.compareWithGold; +import static jaxp.library.JAXPTestUtilities.compareLinesWithGold; +import org.testng.Assert; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +/* + * @test + * @bug 8268457 + * @library /javax/xml/jaxp/libs + * @run testng transform.SurrogateTest + * @summary XML Transformer outputs Unicode supplementary character incorrectly to HTML + */ +@Listeners({jaxp.library.FilePolicy.class}) +public class SurrogateTest { + + final static String TEST_SRC = System.getProperty("test.src", "."); + + @Test + public void toHTMLTest() throws Exception { + String out = "SurrogateTest1out.html"; + String expected = TEST_SRC + File.separator + "SurrogateTest1.html"; + String xml = TEST_SRC + File.separator + "SurrogateTest1.xml"; + String xsl = TEST_SRC + File.separator + "SurrogateTest1.xsl"; + + try (FileInputStream tFis = new FileInputStream(xsl); + InputStream fis = new FileInputStream(xml); + FileOutputStream fos = new FileOutputStream(out)) { + + Source tSrc = new StreamSource(tFis); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer t = tf.newTransformer(tSrc); + t.setOutputProperty("method", "html"); + + Source src = new StreamSource(fis); + Result res = new StreamResult(fos); + t.transform(src, res); + } + Assert.assertTrue(compareWithGold(expected, out)); + } + + @Test + public void handlerTest() throws Exception { + File xmlFile = new File(TEST_SRC, "SurrogateTest2.xml"); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setNamespaceAware(true); + SAXParser sp = spf.newSAXParser(); + TestHandler th = new TestHandler(); + sp.parse(xmlFile, th); + Assert.assertTrue(compareLinesWithGold(TEST_SRC + File.separator + "SurrogateTest2.txt", th.lines)); + } + + private static class TestHandler extends DefaultHandler { + private List lines = new ArrayList<>(); + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + lines.add( localName + "@attr:" + attributes.getValue("attr")); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAncestorsTest.java openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAncestorsTest.java --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAncestorsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathAncestorsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,186 @@ +/* + * 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. + */ +package xpath; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/* + * @test + * @bug 8289508 + * @library /javax/xml/jaxp/unittest + * @run testng/othervm xpath.XPathAncestorsTest + * @summary Tests for XPath ancestor and ancestor-or-self axis specifiers. + */ +public class XPathAncestorsTest { + + private static final String XML = + "\n" + + " \n" + + " \n" + + " <author id=\"1\"/>\n" + + " <isbn>1234</isbn>\n" + + " </book>\n" + + " <book id=\"2\" lang=\"en\">\n" + + " <title/>\n" + + " <author id=\"2\"/>\n" + + " <isbn>5678</isbn>\n" + + " </book>\n" + + "</store>\n" + ; + private static final Document doc; + + static { + try { + var builder = + DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputStream s = new ByteArrayInputStream(XML.getBytes()); + doc = builder.parse(s); + } catch (Exception e) { + System.out.println("Exception while initializing XML document"); + throw new RuntimeException(e.getMessage()); + } + } + + /* + * DataProvider:provides XPath expression using ancestor/ancestor-or-self + * and the expected node(s) from the expression + */ + @DataProvider(name = "ancestors_axes") + public Object[][] getXPathAncestors() { + return new Object[][]{ + //test ancestor + + // abbreviated text + {"//author/ancestor::book/ancestor::store", "/store"}, + {"//isbn/ancestor::store", "/store"}, + {"//ancestor::book[1]", "//book[1]"}, + + // any node + {"//book/ancestor::*", "/store"}, + {"//author/ancestor::*[ancestor::store]/ancestor::store", "/store"}, + {"//author/ancestor::node()[ancestor::store]", "//book"}, + + // dot reference + {"//author/ancestor::book/..", "/store"}, + {"//author/ancestor::*[ancestor::store]/..", "/store"}, + {"//ancestor::book/..", "/store"}, + + // attributes + {"//author/ancestor::*[@id]/parent::*", "/store"}, + {"//author/parent::*[@id]/ancestor::*", "/store"}, + {"//author[@id='1']/ancestor::book[1]", "//book[1]"}, + {"//author[@*]/ancestor::book[1]", "//book[1]"}, + + //test ancestor-or-self + + // any node, indexing, id + {"/store/ancestor-or-self::*", "/store"}, + {"//book[*]/ancestor-or-self::book[1]", "//book[1]"}, + {"/store/book[@*]/ancestor-or-self::book[1]", "//book[1]"}, + {"//book[@id='1']/ancestor-or-self::book[1]", "//book[1]"}, + {"//author[@id='2']/ancestor-or-self::book", "//book[2]"}, + {"//book[1]/ancestor-or-self::store", "/store"}, + + }; + } + + /* + * DataProvider: provides XPath expressions that return empty NodeSet + */ + @DataProvider(name = "emptyNodeSet") + public Object[][] getEmptyNodeSet() { + return new Object[][]{ + // test ancestor + + // abbreviated text + {"/store/book/ancestor::book"}, + {"//author/ancestor::store[2]"}, + {"//author[3]/ancestor::store"}, + + // any nodes + {"/store/ancestor::*"}, + {"/store/book[3]/ancestor::*"}, + {"//book[*]/../ancestor::*"}, + {"/store/book[@id='3']/ancestor::*"}, + {"//book/ssn/ancestor::*"}, + {"//author/ancestor::*[ancestor::isbn]"}, + {"/store/../ancestor::*"}, + {"//ancestor::author"}, + + // id + {"/store/book[@id='3']/ancestor::*"}, + {"/store[@*]/ancestor::*"}, + {"/book[@*]/ancestor::*/ancestor::*"}, + {"//book[@category]/ancestor::*"}, + + //test ancestor-or-self + + // any nodes, id + {"/store/../ancestor-or-self::*"}, + {"//book[3]/ancestor-or-self::*"}, + {"//author/ancestor-or-self::title"}, + {"//author[@id='2']/ancestor-or-self::*[@id='1']"}, + }; + } + + /** + * Verifies XPath ancestor and ancestor-or-self axis specifiers + * by comparing expression and expected result. + * @param exp XPath expression + * @param expected expected result + * @throws Exception if test failed + */ + @Test(dataProvider = "ancestors_axes") + void testXPathAncestors(String exp, String parent) throws Exception { + XPath xPath = XPathFactory.newInstance().newXPath(); + Node result = xPath.evaluateExpression(exp, doc, Node.class); + Node expected = xPath.evaluateExpression(parent, doc, Node.class); + Assert.assertEquals(result, expected); + } + + /** + * Verifies no nodes returned from the XPath expression. + * + * @param exp XPath expression + * @throws Exception + */ + @Test(dataProvider = "emptyNodeSet") + void testEmptyNodeSet(String exp) throws Exception { + XPath xPath = XPathFactory.newInstance().newXPath(); + Node result = xPath.evaluateExpression(exp, doc, Node.class); + Assert.assertEquals(result, null); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathPrecedingTest.java openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathPrecedingTest.java --- openjdk-lts-11.0.20.1+1/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathPrecedingTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jaxp/javax/xml/jaxp/unittest/xpath/XPathPrecedingTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,185 @@ +/* + * 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. + */ +package xpath; + +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +/* + * @test + * @bug 8289508 + * @library /javax/xml/jaxp/unittest + * @run testng/othervm xpath.XPathPrecedingTest + * @summary Tests for XPath preceding and preceding-sibling axis specifiers. + */ +public class XPathPrecedingTest { + + private static final String XML = + "<store>\n" + + " <book id=\"1\" lang=\"en\">\n" + + " <title>Book1\n" + + " \n" + + " 1234\n" + + " \n" + + " \n" + + " Book2\n" + + " \n" + + " 5678\n" + + " \n" + + "\n" + ; + private static final Document doc; + + static { + try { + var builder = + DocumentBuilderFactory.newInstance().newDocumentBuilder(); + InputStream s = new ByteArrayInputStream(XML.getBytes()); + doc = builder.parse(s); + } catch (Exception e) { + System.out.println("Exception while initializing XML document"); + throw new RuntimeException(e.getMessage()); + } + } + + /* + * DataProvider: provides XPath expression using preceding/preceding-sibling + * and the expected node(s) from the expression + */ + @DataProvider(name = "preceding_axes") + public Object[][] getXPathPreceding() { + return new Object[][]{ + // test preceding + + // any nodes + {"/store/book[1]/author/preceding::*", "/store/book[1]/title"}, + + // abbreviated text + {"/store/book[1]/isbn/preceding::*[1]", "/store/book[1]/author"}, + {"(/store/book[1]/isbn/preceding::*)[1]", "/store/book[1]/title"}, + {"//isbn/preceding::book", "//book[1]"}, + {"//book[2]/preceding::book", "//book[1]"}, + {"/store/book[preceding::book]", "//book[2]"}, + {"/store/book[preceding::book]/preceding::book", "//book[1]"}, + + // id + {"//author[@id='2']/../preceding::book", "//book[1]"}, + {"//author[@id='2']/preceding::node()/preceding::book", "//book[1]"}, + {"//author[@id='1']/preceding::title", "//book[1]/title"}, + + //test preceding-sibling + + // any node + {"/store/book[1]/author/preceding-sibling::*", "/store/book[1]/title"}, + {"/store/book[2]/preceding-sibling::*", "//book[1]"}, + {"//author/preceding-sibling::*", "//title"}, + + // abbreviated text + {"/store/book[preceding::book]/preceding-sibling::book", "//book[1]"}, + + // id + {"/store/book[1]/isbn[preceding-sibling::author[@id='1']]", "/store/book[1]/isbn"}, + + }; + } + + /* + * DataProvider: provides XPath expressions that return empty NodeSet + */ + @DataProvider(name = "emptyNodeSet") + public Object[][] getEmptyNodeSet() { + return new Object[][]{ + //test preceding + + // abbreviated text + {"/store/preceding::book"}, + {"/store/book[1]/author/preceding::author"}, + + // any nodes/id + {"/store/book[1]/preceding::*"}, + {"/store/book[1]/title/preceding::*"}, + {"/store/book[@id='1']/preceding::*"}, + + //test preceding-sibling + + // any nodes + {"/store/book[1]/preceding-sibling::*"}, + {"/store/book[2]/title/preceding-sibling::*"}, + + // abbreviated text / id + {"/store/book[1]/author/preceding-sibling::isbn"}, + {"//author[@id='2']/preceding-sibling::book"}, + {"//author[@id='2']/preceding-sibling::node()/preceding-sibling::author"}, + + // attribute / namespace + {"/store/book[2]/@id/preceding-sibling::*"}, + {"/store/book/@lang/preceding-sibling::*"}, + {"/store/book[2]/namespace::*/preceding-sibling::*"}, + + // text node + {"/store/book[2]/isbn/text()/preceding-sibling::*"}, + + }; + } + + /** + * Verifies XPath preceding and preceding-sibling axis specifiers by + * comparing expression and expected result. + * @param exp XPath expression + * @param expected expected result + * @throws Exception if test failed + */ + @Test(dataProvider = "preceding_axes") + void testXPathPreceding(String exp, String parent) throws Exception { + XPath xPath = XPathFactory.newInstance().newXPath(); + Node result = xPath.evaluateExpression(exp, doc, Node.class); + Node expected = xPath.evaluateExpression(parent, doc, Node.class); + Assert.assertEquals(result, expected); + } + + /** + * Verifies no nodes returned from the XPath expression. + * + * @param exp XPath expression + * @throws Exception + */ + @Test(dataProvider = "emptyNodeSet") + void testEmptyNodeSet(String exp) throws Exception { + XPath xPath = XPathFactory.newInstance().newXPath(); + Node result = xPath.evaluateExpression(exp, doc, Node.class); + Assert.assertEquals(result, null); + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/cds/CDSJDITest.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/cds/CDSJDITest.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/cds/CDSJDITest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/cds/CDSJDITest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, 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 @@ -73,7 +73,7 @@ "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./SharedArchiveFile.jsa", "-XX:ExtraSharedClassListFile=" + jarClasslistFile.getPath(), "-Xshare:dump"); - OutputAnalyzer outputDump = executeAndLog(pb, "exec"); + OutputAnalyzer outputDump = executeAndLog(pb, "dump"); for (String jarClass : jarClasses) { outputDump.shouldNotContain("Cannot find " + jarClass); } @@ -81,7 +81,7 @@ outputDump.shouldHaveExitValue(0); // Run the test specified JDI test - pb = ProcessTools.createJavaProcessBuilder(true, testArgs); + pb = ProcessTools.createTestJvm(testArgs); OutputAnalyzer outputRun = executeAndLog(pb, "exec"); try { outputRun.shouldContain("sharing"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/JdbOptions.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/JdbOptions.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/JdbOptions.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/JdbOptions.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020, 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 + * @bug 8234808 + * + * @library /test/lib + * @run main/othervm JdbOptions + */ + +import jdk.test.lib.Platform; +import lib.jdb.Jdb; +import lib.jdb.JdbCommand; +import jdk.test.lib.process.OutputAnalyzer; + +import java.lang.management.ManagementFactory; +import java.util.Arrays; +import java.util.List; + +class JbdOptionsTarg { + static final String OK_MSG = "JbdOptionsTarg: OK"; + + static String argString(String s) { + return "arg >" + s + "<"; + } + + static String propString(String name, String value) { + return "prop[" + name + "] = >" + value + "<"; + } + + public static void main(String[] args) { + System.out.println(OK_MSG); + // print all args + List vmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); + for (String s: vmArgs) { + System.out.println(argString(s)); + } + // print requested sys.props + for (String p: args) { + System.out.println(propString(p, System.getProperty(p))); + } + } +} + +public class JdbOptions { + private static final String targ = JbdOptionsTarg.class.getName(); + + public static void main(String[] args) throws Exception { + // the simplest case + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-client -XX:+PrintVMOptions,main=" + targ) + .expectedArg("-XX:+PrintVMOptions"); + + // pass property through 'options' + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-Dboo=foo',main=" + targ + " boo") + .expectedProp("boo", "foo"); + + // property with spaces + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=\"-Dboo=foo 2\",main=" + targ + " boo") + .expectedProp("boo", "foo 2"); + + // property with spaces (with single quotes) + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-Dboo=foo 2',main=" + targ + " boo") + .expectedProp("boo", "foo 2"); + + // properties with spaces (with single quotes) + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-Dboo=foo '-Dboo2=foo 2',main=" + targ + " boo boo2") + .expectedProp("boo", "foo") + .expectedProp("boo2", "foo 2"); + + // 'options' contains commas - values are quoted (double quotes) + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=\"-client\" \"-XX:+PrintVMOptions\"" + + " -XX:+IgnoreUnrecognizedVMOptions" + + " \"-XX:StartFlightRecording=dumponexit=true,maxsize=500M\" \"-XX:FlightRecorderOptions=repository=jfrrep\"" + + ",main=" + targ) + .expectedArg("-XX:StartFlightRecording=dumponexit=true,maxsize=500M") + .expectedArg("-XX:FlightRecorderOptions=repository=jfrrep"); + + // 'options' contains commas - values are quoted (single quotes) + test("-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-client' '-XX:+PrintVMOptions'" + + " -XX:+IgnoreUnrecognizedVMOptions" + + " '-XX:StartFlightRecording=dumponexit=true,maxsize=500M' '-XX:FlightRecorderOptions=repository=jfrrep'" + + ",main=" + targ) + .expectedArg("-XX:StartFlightRecording=dumponexit=true,maxsize=500M") + .expectedArg("-XX:FlightRecorderOptions=repository=jfrrep"); + + // java options are specified in 2 ways, with and without spaces + // options are quoted by using single and double quotes. + test("-Dprop1=val1", + "-Dprop2=val 2", + "-connect", + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-Dprop3=val3 '-Dprop4=val 4'" + + " -XX:+IgnoreUnrecognizedVMOptions" + + " \"-XX:StartFlightRecording=dumponexit=true,maxsize=500M\"" + + " '-XX:FlightRecorderOptions=repository=jfrrep'" + + ",main=" + targ + " prop1 prop2 prop3 prop4") + .expectedProp("prop1", "val1") + .expectedProp("prop2", "val 2") + .expectedProp("prop3", "val3") + .expectedProp("prop4", "val 4") + .expectedArg("-XX:StartFlightRecording=dumponexit=true,maxsize=500M") + .expectedArg("-XX:FlightRecorderOptions=repository=jfrrep"); + + } + + private static class TestResult { + OutputAnalyzer out; + TestResult(OutputAnalyzer output) { + out = output; + } + TestResult expectedArg(String s) { + out.shouldContain(JbdOptionsTarg.argString(s)); + return this; + } + TestResult expectedProp(String name, String value) { + out.shouldContain(JbdOptionsTarg.propString(name, value)); + return this; + } + } + + private static TestResult test(String... args) throws Exception { + System.out.println(); + System.out.println("...testcase..."); + if (Platform.isWindows()) { + // on Windows we need to escape quotes + args = Arrays.stream(args) + .map(s -> s.replace("\"", "\\\"")) + .toArray(String[]::new); + } + try (Jdb jdb = new Jdb(args)) { + jdb.waitForSimplePrompt(1024, true); // 1024 lines should be enough + jdb.command(JdbCommand.run().allowExit()); + OutputAnalyzer out = new OutputAnalyzer(jdb.getJdbOutput()); + out.shouldContain(JbdOptionsTarg.OK_MSG); + return new TestResult(out); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/JITDebug.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/JITDebug.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/JITDebug.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/JITDebug.java 2023-10-06 05:33:33.000000000 +0000 @@ -104,7 +104,7 @@ } void testLaunch() { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true); + ProcessBuilder pb = ProcessTools.createTestJvm(); List largs = pb.command(); largs.add("-classpath"); largs.add(Utils.TEST_CLASSES); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java 2023-10-06 05:33:33.000000000 +0000 @@ -68,7 +68,6 @@ private String transport = "dt_socket"; private String address = null; private boolean suspended = true; - private boolean addTestVmAndJavaOptions = true; private Launcher(String mainClass) { this.mainClass = mainClass; @@ -96,11 +95,6 @@ suspended = value; return this; } - // default is "true" - public Launcher addTestVmAndJavaOptions(boolean value) { - addTestVmAndJavaOptions = value; - return this; - } public ProcessBuilder prepare() { List debuggeeArgs = new LinkedList<>(); @@ -109,8 +103,7 @@ + ",server=y,suspend=" + (suspended ? "y" : "n")); debuggeeArgs.addAll(options); debuggeeArgs.add(mainClass); - return ProcessTools.createJavaProcessBuilder(addTestVmAndJavaOptions, - debuggeeArgs.toArray(new String[0])); + return ProcessTools.createTestJvm(debuggeeArgs); } public Debuggee launch(String name) { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/OptionTest.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/OptionTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/OptionTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/OptionTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -33,8 +33,6 @@ * @run driver OptionTest */ -import java.net.ServerSocket; -import java.util.regex.Matcher; import java.util.regex.Pattern; public class OptionTest extends Object { @@ -127,18 +125,12 @@ } public static void main(String[] args) throws Exception { - // find a free port - ServerSocket ss = new ServerSocket(0); - int port = ss.getLocalPort(); - ss.close(); - String address = String.valueOf(port); - String javaExe = System.getProperty("java.home") + java.io.File.separator + "bin" + java.io.File.separator + "java"; String targetClass = "HelloWorld"; String baseOptions = "transport=dt_socket" + - ",address=" + address + + ",address=0" + ",server=y" + ",suspend=n"; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/PrivateTransportTest.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/PrivateTransportTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/PrivateTransportTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/PrivateTransportTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -82,7 +82,7 @@ String libName = transportLib.getFileName().toString().replace("dt_socket", "private_dt_socket"); Files.copy(transportLib, Paths.get(Utils.TEST_CLASSES).resolve(libName)); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-agentlib:jdwp=transport=private_dt_socket,server=y,suspend=n", "-classpath", Utils.TEST_CLASSES, "HelloWorld"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/RunToExit.java openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/RunToExit.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/jdi/RunToExit.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/jdi/RunToExit.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -30,7 +30,6 @@ * @build VMConnection RunToExit Exit0 * @run driver RunToExit */ -import java.net.ServerSocket; import com.sun.jdi.Bootstrap; import com.sun.jdi.VirtualMachine; import com.sun.jdi.event.*; @@ -41,6 +40,8 @@ import java.util.List; import java.util.Iterator; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import jdk.test.lib.process.ProcessTools; @@ -50,6 +51,9 @@ static volatile int error_seen = 0; static volatile boolean ready = false; + /* port the debuggee is listening on */ + private static String address; + /* * Find a connector by name */ @@ -66,12 +70,11 @@ } /* - * Launch a server debuggee with the given address + * Launch a server debuggee, detect debuggee listening port */ - private static Process launch(String address, String class_name) throws Exception { + private static Process launch(String class_name) throws Exception { String args[] = new String[]{ - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" - + address, + "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=0", class_name }; args = VMConnection.insertDebuggeeVMOptions(args); @@ -92,8 +95,17 @@ return p; } + /* warm-up predicate for debuggee */ + private static Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b"); + private static boolean isTransportListening(String line) { - return line.startsWith("Listening for transport dt_socket"); + Matcher m = listenRegexp.matcher(line); + if (!m.matches()) { + return false; + } + // address is 2nd group + address = m.group(2); + return true; } private static void checkForError(String line) { @@ -103,28 +115,21 @@ } /* - * - pick a TCP port - * - Launch a server debuggee: server=y,suspend=y,address=${port} + * - Launch a server debuggee: server=y,suspend=y,address=0 + * - detect the port debuggee is listening on * - run it to VM death * - verify we saw no error */ public static void main(String args[]) throws Exception { - // find a free port - ServerSocket ss = new ServerSocket(0); - int port = ss.getLocalPort(); - ss.close(); - - String address = String.valueOf(port); - // launch the server debuggee - Process process = launch(address, "Exit0"); + Process process = launch("Exit0"); // attach to server debuggee and resume it so it can exit AttachingConnector conn = (AttachingConnector)findConnector("com.sun.jdi.SocketAttach"); Map conn_args = conn.defaultArguments(); Connector.IntegerArgument port_arg = (Connector.IntegerArgument)conn_args.get("port"); - port_arg.setValue(port); + port_arg.setValue(address); System.out.println("Connection arguments: " + conn_args); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/net/httpserver/bugs/B6393710.java openjdk-lts-11.0.21+9/test/jdk/com/sun/net/httpserver/bugs/B6393710.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/net/httpserver/bugs/B6393710.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/net/httpserver/bugs/B6393710.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -24,6 +24,7 @@ /** * @test * @bug 6393710 + * @library /test/lib * @summary Non authenticated call followed by authenticated call never returns */ @@ -34,6 +35,8 @@ import java.io.*; import java.net.*; +import jdk.test.lib.Utils; + /* * Test checks for following bug(s) when a POST containing a request body * needs to be authenticated @@ -77,7 +80,7 @@ server.start (); Socket s = new Socket ("localhost", server.getAddress().getPort()); - s.setSoTimeout (5000); + s.setSoTimeout ((int) Utils.adjustTimeout(5000)); OutputStream os = s.getOutputStream(); os.write (cmd.getBytes()); @@ -124,8 +127,8 @@ return false; } - public static boolean ok = false; - static int requests = 0; + public static volatile boolean ok = false; + static volatile int requests = 0; static class Handler implements HttpHandler { int invocation = 1; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/com/sun/net/httpserver/SimpleHttpServerTest.java openjdk-lts-11.0.21+9/test/jdk/com/sun/net/httpserver/SimpleHttpServerTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/com/sun/net/httpserver/SimpleHttpServerTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/com/sun/net/httpserver/SimpleHttpServerTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -24,8 +24,12 @@ /** * @test * @bug 8015692 + * @key intermittent * @summary Test HttpServer instantiation, start, and stop repeated in a loop - * Testing for Bind exception on Windows + * Testing for Bind exception on Windows. This test may fail + * intermittently if other tests / process manage to bind to + * the same port that the test is using in the short window + * time where the port might appear available again. */ import java.net.InetSocketAddress; @@ -41,24 +45,40 @@ System.out.println(System.getProperty("java.version")); InetSocketAddress serverAddr = new InetSocketAddress(0); HttpServer server = HttpServer.create(serverAddr, 0); - final int serverPort = server.getAddress().getPort(); + int serverPort = server.getAddress().getPort(); server.start(); server.stop(0); serverAddr = new InetSocketAddress(serverPort); int exceptionCount = 0; + boolean failedOnce = false; System.out.println("Using serverPort == " + serverPort); - for (int i = 0; i < 100; i++) { - try { - server = HttpServer.create(serverAddr, 0); - server.start(); - server.stop(0); - } catch (Exception ex) { - ex.printStackTrace(); - exceptionCount++; + RETRY: while (exceptionCount == 0) { + for (int i = 0; i < 100; i++) { + try { + server = HttpServer.create(serverAddr, 0); + server.start(); + server.stop(0); + } catch (Exception ex) { + if (!failedOnce) { + failedOnce = true; + server = HttpServer.create(new InetSocketAddress(0), 0); + serverPort = server.getAddress().getPort(); + server.start(); + server.stop(0); + serverAddr = new InetSocketAddress(serverPort); + System.out.println("Retrying with serverPort == " + serverPort); + continue RETRY; + } + System.err.println("Got exception at iteration: " + i ); + ex.printStackTrace(); + exceptionCount++; + } } + break; } if (exceptionCount > 0) { - throw new RuntimeException("Test Failed"); + throw new RuntimeException("Test Failed: got " + + exceptionCount + " exceptions."); } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceConsumeMouseEvents.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6251988 + @summary PIT: Choice consumes MouseReleased, MouseClicked events when clicking it with left button, + @key headful +*/ + +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceConsumeMouseEvents { + + static volatile Frame frame; + static volatile Robot robot; + static volatile Choice choice1 = new Choice(); + static volatile boolean mousePressed = false; + static volatile boolean mouseReleased = false; + static volatile boolean mouseClicked = false; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + for (int i = 1; i<10; i++){ + choice1.add("item-0"+i); + } + choice1.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + mousePressed = true; + System.out.println(me); + } + public void mouseReleased(MouseEvent me) { + mouseReleased = true; + System.out.println(me); + } + public void mouseClicked(MouseEvent me) { + mouseClicked = true; + System.out.println(me); + } + }); + + frame = new Frame("ChoiceConsumeMouseEvents"); + frame.add(choice1); + frame.setSize(400, 400); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + static void runTest() { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + testMouseClick(InputEvent.BUTTON1_DOWN_MASK, 0); + robot.delay(100); + testMouseClick(InputEvent.BUTTON1_DOWN_MASK, 100); + } catch (Throwable e) { + throw new RuntimeException("Test failed. Exception thrown: "+e); + } + } + + static void testMouseClick(int button, int delay) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(button); + robot.delay(delay); + robot.mouseRelease(button); + robot.delay(200); + if (!(mousePressed && + mouseReleased && + mouseClicked)) + { + throw new RuntimeException("Test failed. Choice should generate PRESSED, RELEASED, CLICKED events"); + } else { + System.out.println("Test passed. Choice generated MouseDragged PRESSED, RELEASED, CLICKED events"); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + mousePressed = false; + mouseReleased = false; + mouseClicked = false; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceFocusLostTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * 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 4338368 + @summary Tests that choice doesn't throw spurious mouse events when losing focus + @key headful +*/ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceFocusLostTest { + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_TAB); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_TAB); + robot.waitForIdle(); + robot.delay(1000); + if (!client.isPassed()) { + throw new RuntimeException("Test failed: choice fires spurious events"); + } else { + System.out.println("Test passed."); + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static volatile Frame frame; + static volatile ChoiceBug client; + + static void createUI() { + frame = new Frame("ChoiceFocusLostTest"); + client = new ChoiceBug(); + frame.add(client); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +} + +class ChoiceBug extends Panel { + + volatile boolean passed = true; + + public ChoiceBug() { + Choice choice = new Choice(); + choice.add("item-1"); + choice.add("item-2"); + Button button = new Button("Button"); + add(choice); + add(button); + choice.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent me) { + passed = false; + } + public void mouseClicked(MouseEvent me) { + passed = false; + } + }); + choice.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Focus Gained"); + System.out.println(fe); + } + public void focusLost(FocusEvent fe) { + System.out.println("Got expected FocusLost event."); + System.out.println(fe); + } + }); + setSize(400, 400); + choice.requestFocus(); + } + + public boolean isPassed() { + return passed; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceFreezeTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceFreezeTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceFreezeTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceFreezeTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,132 @@ +/* + * 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 4303064 + @summary Tests that choice doesn't freeze display when its container is + disabled and enabled after. + @key headful +*/ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceFreezeTest { + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static volatile Frame frame; + static volatile ChoiceFreezeBug client; + + static void createUI() { + frame = new Frame("ChoiceFreezeTest"); + client = new ChoiceFreezeBug(); + frame.add(client); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + client.init(); + } + + static void runTest() throws Exception { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(2000); + robot.mouseMove(client.choice.getLocationOnScreen().x + 1, client.choice.getLocationOnScreen().y + 1); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.mouseMove(client.button.getLocationOnScreen().x + 3, client.button.getLocationOnScreen().y + 3); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(6000); + + if (!client.isPassed()) { + throw new RuntimeException("Test failed: display is frozen."); + } + } +} + +class ChoiceFreezeBug extends Panel { + + volatile Button button; + volatile Choice choice; + volatile ChoiceMouseListener listener = new ChoiceMouseListener(); + + public ChoiceFreezeBug() { + choice = new Choice(); + choice.addItem("Item 1"); + choice.addItem("Item 2"); + button = new Button("Button"); + add(choice); + add(button); + button.addMouseListener(listener); + setEnabled(false); + } + + void init() { + setEnabled(true); + choice.requestFocus(); + } + + public boolean isPassed() { + return listener.isPassed(); + } +} + +class ChoiceMouseListener extends MouseAdapter { + + volatile boolean passed = false; + + public void mouseReleased(MouseEvent e) { + passed = true; + } + + public void mousePressed(MouseEvent e) { + passed = true; + } + + public boolean isPassed() { + return passed; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceGeneratesItemEvents.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,129 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6239941 + @summary Choice triggers ItemEvent when selecting an item with right mouse button, Xtoolkit + @key headful + @requires (os.family == "linux") +*/ + +import java.awt.Choice; +import java.awt.Color; +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.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyEvent; + +public class ChoiceGeneratesItemEvents implements ItemListener { + + public static void main(String[] args) throws Exception { + if (!System.getProperty("os.name").toLowerCase().startsWith("linux")) { + System.out.println("This test is for Linux only"); + return; + } + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + + } + } + } + + static volatile Frame frame; + static volatile Robot robot; + static volatile Choice choice1; + static volatile boolean passed = true; + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<10; i++){ + choice1.add("item-0"+i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + choice1.addItemListener(new ChoiceGeneratesItemEvents()); + frame = new Frame("ChoiceGeneratesItemEvents"); + frame.add(choice1); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + testMousePressOnChoice(InputEvent.BUTTON2_DOWN_MASK); + testMousePressOnChoice(InputEvent.BUTTON3_DOWN_MASK); + if (!passed) { + throw new RuntimeException("Test failed."); + } else { + System.out.println("Test passed. "); + } + } + + static void testMousePressOnChoice(int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(2000); + + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 2 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + if (!color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice wasn't open with LEFTMOUSE button." +button); + } + robot.mouseMove(pt.x + choice1.getWidth()/2, + pt.y + 5*choice1.getHeight()); + 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); + } + + public void itemStateChanged(ItemEvent ie) { + System.err.println("Opened Choice generated ItemEvent on RIGHT/MIDDLE mouse press." +ie); + passed = false; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent_2.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,340 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6239944 + @summary PIT: Right clicking on the scrollbar of the choice's dropdown disposes the drop-down, on XToolkit + @key headful + @requires (os.family == "linux" | os.family == "windows") +*/ + +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceHandleMouseEvent_2 { + + static Robot robot; + static volatile Choice choice1; + static volatile Frame frame; + static boolean isWindows; + + public static void main(String[] args) throws Exception { + String os = System.getProperty("os.name").toLowerCase(); + if (!os.startsWith("windows") && !os.startsWith("linux")) { + System.out.println("This test is only for Windows and Linux"); + return; + } + isWindows = os.startsWith("windows"); + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<50; i++) { + choice1.add("item-0"+i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + frame = new Frame("ChoiceHandleMouseEvent_2"); + frame.setBackground(Color.green); + Panel panel = new Panel(); + panel.setBackground(Color.green); + panel.add(choice1); + frame.add(panel); + frame.setSize(300,300); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(100); + + /* + * Stage 1. Choice should be closed if user dragged mouse + * outside of Choice after opening it. + * Should only pass on Windows or XAWT. + * Choice on motif might be opened only by click on small box + * in the right side. + */ + testDragMouseButtonOut(InputEvent.BUTTON1_DOWN_MASK); + System.out.println("Passed Stage 1: Choice should be closed if mouse dragged out."); + + /* + * Stage 2: Choice should be closed if LeftMouse drag finished + * on Scrollbar. This involeves only one + * MousePress and one MouseRelease event + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testDragMouseButtonOnSB(InputEvent.BUTTON1_DOWN_MASK); + System.out.println("Passed Stage 2: Choice should be closed if " + + "LeftMouse drag finished on Scrollbar."); + + /* + * Stage 3: Pressing RIGHT/MIDDLE MouseButton on Scrollbar + * shouldn't close Choice's pop-down menu. + * Pressing LEFT MouseButton shouldn't close it too. It should + * scroll it. + * This is an unstable test because we doesn't have an API to + * get Scrollbar from Choice. There is a possibility not to + * hit the scrollbar that couldn't been predicted. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testPressOnScrollbar(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK); + testPressOnScrollbar(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 3: Choice correctly reacts on mouse click on its Scrollbar."); + + /* + * Stage 4: Choice should close its popdown menu if user opened a Choice then + * releases Mouse and then presses Mouse again and dragged it on Choice's Scrollbar + * This involves only one MousePress and one MouseRelease + * event, so it differs from Stage 2. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu or scrollbar + testDragMouseOnScrollbar(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON1_DOWN_MASK); + System.out.println("Passed Stage 4: Choice should close if user opened a " + + "Choice then releases Mouse and then presses Mouse again " + + "and drag it on Choice's Scrollbar ."); + } + + + //Stage 4 + static void testDragMouseOnScrollbar(int openButton, int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.mousePress(button); + /*X-coordinate should be closer to right edge of Choice, so + divider 4 is used. */ + dragMouse(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2, + pt.x + choice1.getWidth() - choice1.getHeight()/4, pt.y + 5*choice1.getHeight()); + robot.mouseRelease(button); + robot.delay(200); + + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + if (color.equals(Color.red)) { + throw new RuntimeException( + "Test failed. Choice didn't close after drag without firstPress on ScrollBar " + button); + } else { + System.out.println("Stage 4 passed."+ button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + //stage 3 + static void testPressOnScrollbar(int openButton, int button) { + if (!isWindows) { + return; // Windows-only tests. + } + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + /*X-coordinate should be closer to right edge of Choice, so + divide by 4 is used. */ + int px = pt.x + choice1.getWidth() - choice1.getHeight()/4; + int py = pt.y + 5*choice1.getHeight(); + robot.mouseMove(px, py); + robot.delay(200); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + System.out.println("x= "+px); + System.out.println("y= "+py); + + /* + This is for Windows only. + On XP theme choice become closed on RightMouseClick over a scrollbar. + A system menu is opened after that. On Classic theme Choice doesn't react on it at all. + */ + boolean isXPTheme = false; + Object themeObject = Toolkit.getDefaultToolkit().getDesktopProperty("win.xpstyle.themeActive"); + // it returns null when Classic theme is active but we should + // check it's boolean value anyway if event it's not null. + if (themeObject != null) { + isXPTheme = ((Boolean)themeObject).booleanValue(); + } + System.out.println("isXPTheme="+isXPTheme); + px = pt.x + choice1.getWidth()/2; + py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + System.out.println("RED="+Color.red); + System.out.println("GREEN="+Color.green); + if (isXPTheme && button == InputEvent.BUTTON3_DOWN_MASK) { + if (!color.equals(Color.green)) { + throw new RuntimeException("Stage 3 failed(XP theme). " + + "Choice wasn't closed with pressing button on its Scrollbar" + openButton +":"+button); + } else { + System.out.println("Stage 3 passed(XP theme)." + openButton +":"+button); + } + } else { + if (!color.equals(Color.red)) { + throw new RuntimeException("Stage 3 failed(classic theme). " + + "Choice is being closed with pressing button on its Scrollbar" + openButton +":"+button); + } else { + System.out.println("Stage 3 passed(classic theme)." + openButton +":"+button); + } + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + // Stage 1 + static void testDragMouseButtonOut(int button) { + Point pt = choice1.getLocationOnScreen(); + + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.mousePress(button); + dragMouse(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2, + pt.x + choice1.getWidth()*2, pt.y + choice1.getHeight()/2); + robot.mouseRelease(button); + robot.delay(200); + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + System.out.println("RED="+Color.red); + // fix 6268989: On Windows Choice shouldn't been closed if + // Mouse dragged outside of Choice after one mouse press. + if (isWindows) { + if (color.equals(Color.red)) { + System.out.println("Stage 1 passed. On Windows Choice shouldn't be " + + "closed if Mouse dragged outside of Choice after one mouse press "+button); + } else { + throw new RuntimeException("Test failed. Choice on Windows shouldn't be " + + "closed after drag outside of Choice after one mouse press "+button); + } + } else { + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice didn't close " + + "after drag outside of Choice "+button); + } else { + System.out.println("Stage 1 passed."+ button); + } + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + //stage 2 + static void testDragMouseButtonOnSB(int button) { + Point pt = choice1.getLocationOnScreen(); + + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.mousePress(button); + /*X-coordinate should be closer to right edge of Choice, so + divider 4 is used. */ + dragMouse(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2, + pt.x + choice1.getWidth() - choice1.getHeight()/4, pt.y + 5*choice1.getHeight()); + robot.mouseRelease(button); + robot.delay(200); + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + if (isWindows) { + if (color.equals(Color.red)) { + System.out.println("Stage 2 passed. On Windows Choice shouldn't be " + + " closed if Mouse dragged on its scrollbar "+button); + } else { + throw new RuntimeException("Test failed. On Windows Choice shouldn't be " + + " closed if Mouse dragged on its scrollbar "+button); + } + } else { + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice didn't close after drag on ScrollBar "+button); + } else { + System.out.println("Stage 2 passed."+ button); + } + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } + + static 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); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceHandleMouseEvent.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,206 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 5003166 + @summary REG:Mouse button not validated before bringing up the drop-down menu for choice + @key headful + @requires (os.family == "linux" | os.family == "windows") +*/ + +import java.awt.Choice; +import java.awt.Color; +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.KeyEvent; + +public class ChoiceHandleMouseEvent { + static Robot robot; + static volatile Choice choice1; + static volatile Frame frame; + + public static void main(String[] args) throws Exception { + String os = System.getProperty("os.name").toLowerCase(); + if (!os.startsWith("windows") && !os.startsWith("linux")) { + System.out.println("This test is only for Windows and Linux"); + return; + } + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + choice1.add("item-01"); + choice1.add("item-02"); + choice1.add("item-03"); + choice1.add("item-04"); + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + frame = new Frame("ChoiceHandleMouseEvent"); + frame.add(choice1); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + + /* + * Stage 1: Choice should only opens with LEFTMOUSE click. + * Should only pass on Windows or XAWT. + * Choice on motif might be opened only by click on small box + * in the right side. + */ + testPressMouseButton(InputEvent.BUTTON2_DOWN_MASK); + testPressMouseButton(InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 1: Choice should only opens with LEFT BUTTON."); + + /* + * Stage 2: Choice should only change its value if pressed + * mouse button is LEFTMOUSE. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testPressMouseButton_2(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK); + testPressMouseButton_2(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 2: Choice should not change its value if pressed mouse buttonis not left."); + + /* + * Stage 3: Choice should only react on drags with LEFTMOUSE button. + */ + // first parameter is for opening choice. The second is for + // selecting item inside the menu + testDragMouseButton(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK); + testDragMouseButton(InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK); + System.out.println("Passed Stage 3: Choice should only react on drags with LEFTMOUSE button."); + } + + static void testPressMouseButton(int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(button); + robot.mouseRelease(button); + robot.delay(200); + + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + Color color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("Got color " + color + " at (" + px + "," + py + ")"); + System.out.println("RED="+Color.red); + if (color.equals(Color.red)) { + throw new RuntimeException("Test failed. Choice opens with "+button); + } else { + System.out.println("Stage 1 passed."+ button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static void testPressMouseButton_2(int openButton, int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, + pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + robot.mouseMove(pt.x + choice1.getWidth()/2, + pt.y + 2 * choice1.getHeight()); + robot.mousePress(button); + robot.mouseRelease(button); + + System.out.println(); + + if (choice1.getSelectedIndex() == 0) { + System.out.println("Stage 2 passed." + openButton +":"+button); + } else { + throw new RuntimeException("Stage 2 failed." + openButton +":"+button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static void testDragMouseButton(int openButton, int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + + robot.mousePress(button); + dragMouse(pt.x + choice1.getWidth()/2, pt.y + + choice1.getHeight()/2, + pt.x + choice1.getWidth()/2, + pt.y + 2 * choice1.getHeight()); + robot.mouseRelease(button); + + if (choice1.getSelectedIndex() == 0 ){ + System.out.println("Stage 3 passed." + openButton +":"+button); + // System.out.println("choice1.getSelectedIndex()" + choice1.getSelectedIndex()); + } else { + throw new RuntimeException("Stage 3 failed." + openButton +":"+button); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + } + + static 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); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceMouseEventOutbounds.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,145 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6272965 + @summary PIT: Choice triggers MousePressed when pressing mouse outside comp while drop-down is active, XTkt + @key headful +*/ + +import java.awt.Choice; +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.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ChoiceMouseEventOutbounds { + + static final int DELAY = 100; + static volatile Choice choice1; + static volatile Frame frame; + static volatile Robot robot; + static volatile boolean mousePressed = false; + static volatile boolean mouseReleased = false; + static volatile boolean mouseClicked = false; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<10; i++) { + choice1.add("item "+i); + } + + choice1.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent me) { + mousePressed = true; + System.out.println(me); + } + public void mouseReleased(MouseEvent me) { + mouseReleased = true; + System.out.println(me); + } + public void mouseClicked(MouseEvent me) { + mouseClicked = true; + System.out.println(me); + } + }); + + frame = new Frame("ChoiceMouseEventOutbounds"); + frame.add(choice1); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + static void runTest() throws Exception { + // On Windows, Choice will not close its pop-down menu on a RIGHT + // MousePress outside of the Choice. So this scenario isn't + // tested here for that reason. + + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(DELAY*10); + testMouseClick(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(DELAY); + testMouseClick(InputEvent.BUTTON2_DOWN_MASK); + robot.delay(DELAY); + testMouseClick(InputEvent.BUTTON3_DOWN_MASK); + + System.out.println("Test passed: Choice doesn't generate MOUSEPRESS/CLICK/RELEASE outside Choice."); + } + + static void testMouseClick(int button) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(DELAY); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(DELAY); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(DELAY*3); + + //they are true because we just pressed mouse + mousePressed = false; + mouseReleased = false; + mouseClicked = false; + + //move mouse outside Choice + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y - choice1.getHeight()); + robot.delay(DELAY*3); + robot.mousePress(button); + robot.delay(DELAY); + robot.mouseRelease(button); + + if (mousePressed || mouseReleased || mouseClicked) { + System.out.println("ERROR: "+ mousePressed+","+mouseReleased +","+mouseClicked); + throw new RuntimeException( + "Test failed. Choice shouldn't generate PRESSED, RELEASED, CLICKED events outside "+ button); + } else { + System.out.println( + "Test passed. Choice didn't generated MouseDragged PRESSED, RELEASED, CLICKED events outside "+ button); + } + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(DELAY); + mousePressed = false; + mouseReleased = false; + mouseClicked = false; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceMoveTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceMoveTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceMoveTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceMoveTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * 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 4323906 + @summary Test that Choice location is not updated erroneously + @key headful +*/ + +/** + * summary: The test adds a Choice to a Container with BorderLayout, and + * adds the Container to a Frame with null Layout. When + * the Container is moved in the x direction, the Choice should + * not move in the y direction. + */ + +import java.awt.BorderLayout; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.Frame; + +public class ChoiceMoveTest { + + static volatile Frame frame; + static volatile Container c; + static volatile Choice ch; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + frame = new Frame("Choice Move Test"); + frame.setSize(500, 500); + frame.setLayout(null); + + c = new Container(); + c.setBackground(Color.green); + frame.add(c); + c.setSize(200, 200); + c.setLocation(100, 100); + c.setLayout(new BorderLayout()); + + ch = new Choice(); + ch.setSize(100, 27); + c.add(ch, BorderLayout.SOUTH); + frame.setVisible(true); + frame.validate(); + } + + static void runTest () throws Exception { + Thread.sleep(1000); + // If this test ever gives us problems, try putting getLocation() in a + // ComponentListener. + int xbefore = ch.getLocation().x; + int ybefore = ch.getLocation().y; + System.out.println("Choice location before: " + xbefore + ", " + ybefore); + + c.setLocation(200, 100); + Thread.sleep(1000); + + java.awt.Toolkit.getDefaultToolkit().sync(); + Thread.sleep(1000); + int xafter = ch.getLocation().x; + int yafter = ch.getLocation().y; + System.out.println("Choice location after: " + xafter + ", " + yafter); + + if (ybefore != yafter) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test failed - Choice should not move in the y direction."); + } + else { + System.out.println("Test passed."); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/ChoiceStaysOpenedOnTAB.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,150 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6239938 + @summary Choice drop-down does not disappear when it loses focus, on XToolkit + @key headful + @requires (os.family == "linux") +*/ + +import java.awt.Button; +import java.awt.Choice; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ChoiceStaysOpenedOnTAB { + + static volatile Robot robot; + static volatile Choice choice1; + static volatile Frame frame; + + public static void main(String[] args) throws Exception { + + if (!System.getProperty("os.name").toLowerCase().startsWith("linux")) { + System.out.println("This test is for Linux only"); + return; + } + + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + choice1 = new Choice(); + for (int i = 1; i<10; i++) { + choice1.add("item-0"+i); + } + choice1.setForeground(Color.red); + choice1.setBackground(Color.red); + Button b1 = new Button("FirstButton"); + Button b2 = new Button("SecondButton"); + frame = new Frame("ChoiceStaysOpenedOnTAB"); + Panel panel = new Panel(); + panel.add(b1); + panel.add(choice1); + panel.add(b2); + frame.add(panel); + frame.setSize(400,400); + frame.setLocationRelativeTo(null); + frame.validate(); + frame.setVisible(true); + } + + static void runTest() throws Exception { + + /* + * Choice should not lose focus while it is opened with + * TAB/Shitf-TAB KeyPress on XAWT. + * Should only pass on XAWT. + */ + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(50); + robot.delay(1000); + + testTABKeyPress(InputEvent.BUTTON1_DOWN_MASK, KeyEvent.VK_TAB, false); + testTABKeyPress(InputEvent.BUTTON1_DOWN_MASK, KeyEvent.VK_TAB, true); + System.out.println("Passed : Choice should not lose focus on TAB key press while it is opened."); + } + + static void testTABKeyPress(int openButton, int keyButton, boolean isShiftUsed) { + Point pt = choice1.getLocationOnScreen(); + robot.mouseMove(pt.x + choice1.getWidth()/2, pt.y + choice1.getHeight()/2); + robot.delay(100); + robot.mousePress(openButton); + robot.mouseRelease(openButton); + robot.delay(200); + + Color color = robot.getPixelColor(pt.x + choice1.getWidth()/2, + pt.y + 3 * choice1.getHeight()); + if (!color.equals(Color.red)) { + throw new RuntimeException( + "Choice wasn't opened with LEFTMOUSE button" + openButton +":"+keyButton+":"+isShiftUsed); + } + robot.delay(200); + if (isShiftUsed) { + robot.keyPress(KeyEvent.VK_SHIFT); + } + robot.keyPress(keyButton); + robot.keyRelease(keyButton); + + if (isShiftUsed) { + robot.keyRelease(KeyEvent.VK_SHIFT); + } + + robot.delay(200); + if (!choice1.isFocusOwner()) { + System.out.println("Choice has focus=="+choice1.isFocusOwner()); + throw new RuntimeException( + "Choice has no focus after pressing TAB/Shitf+TAB" + openButton +":"+keyButton+":"+isShiftUsed); + } + int px = pt.x + choice1.getWidth()/2; + int py = pt.y + 3 * choice1.getHeight(); + color = robot.getPixelColor(px, py); + //we should take a color on the point on the choice's menu + System.out.println("color got "+color); + if (!color.equals(Color.red)) { + throw new RuntimeException( + "Choice closed after TAB/Shift+TAB key press" + openButton +":"+keyButton+":"+isShiftUsed); + } + + //close opened choice + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.delay(200); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/DragOffNoSelectTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/DragOffNoSelectTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Choice/DragOffNoSelectTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Choice/DragOffNoSelectTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,134 @@ +/* + * 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 4902933 + @summary Test that dragging off an unfurled Choice prevents selecting a new item + @key headful +*/ + +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.WindowEvent; +import java.awt.event.WindowListener; + +public class DragOffNoSelectTest implements WindowListener, Runnable { + + static volatile DragOffNoSelectTest testInstance; + static volatile Frame frame; + static volatile Choice theChoice; + static volatile Robot robot; + static final String firstItem = new String("First Choice Item"); + + static volatile Object lock = new Object(); + + public static void main(String[] args) throws Exception { + testInstance = new DragOffNoSelectTest(); + robot = new Robot(); + robot.setAutoDelay(500); + try { + EventQueue.invokeAndWait(() -> createUI()); + runTest(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + } + + static void createUI() { + frame = new Frame("DragOffNoSelectTest"); + theChoice = new Choice(); + theChoice.add(firstItem); + for (int i = 0; i < 10; i++) { + theChoice.add(new String("Choice Item " + i)); + } + frame.add(theChoice); + frame.addWindowListener(testInstance); + frame.setSize(400, 400); + frame.setLocationRelativeTo(null); + + frame.setVisible(true); + frame.validate(); + } + + static void runTest() throws Exception { + robot.mouseMove(10, 30); + synchronized (lock) { + try { + lock.wait(120000); + } + catch (InterruptedException e) {} + } + robot.waitForIdle(); + + if (!firstItem.equals(theChoice.getSelectedItem())) { + throw new RuntimeException("TEST FAILED - new item was selected"); + } + } + + public void run() { + robot.delay(1000); + // get loc of Choice on screen + Point loc = theChoice.getLocationOnScreen(); + // get bounds of Choice + Dimension size = theChoice.getSize(); + robot.mouseMove(loc.x + size.width - 10, loc.y + size.height / 2); + + robot.setAutoDelay(500); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + + robot.mouseMove(loc.x + size.width / 2, loc.y + size.height + size.height / 2); + robot.mouseMove(loc.x + size.width / 2, loc.y + 2*size.height + size.height / 2); + robot.mouseMove(loc.x + size.width / 2, loc.y + 3*size.height + size.height / 2); + robot.mouseMove(loc.x + size.width / 2, loc.y + 4*size.height + size.height / 2); + robot.mouseMove(loc.x + size.width, loc.y + 4*size.height + size.height / 2); + robot.mouseMove(loc.x + 2*size.width, loc.y + 4*size.height + size.height / 2); + robot.mouseMove(loc.x + 3*size.width, loc.y + 4*size.height + size.height / 2); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + synchronized(lock) { + lock.notify(); + } + } + + public void windowOpened(WindowEvent e) { + System.out.println("windowActivated()"); + Thread testThread = new Thread(testInstance); + testThread.start(); + } + public void windowActivated(WindowEvent e) { } + public void windowDeactivated(WindowEvent e) {} + public void windowClosed(WindowEvent e) {} + public void windowClosing(WindowEvent e) {} + public void windowIconified(WindowEvent e) {} + public void windowDeiconified(WindowEvent e) {} + +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Clipboard/CopyAnimatedGIFTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Clipboard/CopyAnimatedGIFTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Clipboard/CopyAnimatedGIFTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Clipboard/CopyAnimatedGIFTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,166 @@ +/* + * 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.awt.Canvas; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.util.concurrent.CountDownLatch; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +/* + * @test + * @key headful + * @bug 6176679 + * @summary Tests that an application doesn't freeze when copying an animated + * gif image to the system clipboard. We run the test two times. First with + * image displayed on screen and second with it not displayed. + * @run main CopyAnimatedGIFTest + */ +public class CopyAnimatedGIFTest { + private static final long TIMEOUT = 10000; + + private final CountDownLatch latch = new CountDownLatch(1); + private final Image img = Toolkit.getDefaultToolkit().createImage(imageData); + + private static final byte[] imageData = { + (byte) 0x47, (byte) 0x49, (byte) 0x46, (byte) 0x38, (byte) 0x39, + (byte) 0x61, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x00, + (byte) 0xa1, (byte) 0x03, (byte) 0x00, (byte) 0xff, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0x00, (byte) 0xff, + (byte) 0xff, (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x21, (byte) 0xff, (byte) 0x0b, (byte) 0x4e, (byte) 0x45, + (byte) 0x54, (byte) 0x53, (byte) 0x43, (byte) 0x41, (byte) 0x50, + (byte) 0x45, (byte) 0x32, (byte) 0x2e, (byte) 0x30, (byte) 0x03, + (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x21, + (byte) 0xf9, (byte) 0x04, (byte) 0x00, (byte) 0x0a, (byte) 0x00, + (byte) 0xff, (byte) 0x00, (byte) 0x2c, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x04, + (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x04, (byte) 0x84, + (byte) 0x8f, (byte) 0x09, (byte) 0x05, (byte) 0x00, (byte) 0x21, + (byte) 0xf9, (byte) 0x04, (byte) 0x01, (byte) 0x0a, (byte) 0x00, + (byte) 0x03, (byte) 0x00, (byte) 0x2c, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x04, + (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x04, (byte) 0x94, + (byte) 0x8f, (byte) 0x29, (byte) 0x05, (byte) 0x00, (byte) 0x21, + (byte) 0xf9, (byte) 0x04, (byte) 0x01, (byte) 0x0a, (byte) 0x00, + (byte) 0x03, (byte) 0x00, (byte) 0x2c, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x04, + (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x04, (byte) 0x8c, + (byte) 0x8f, (byte) 0x19, (byte) 0x05, (byte) 0x00, (byte) 0x3b + }; + + private void createGUI() { + ImageCanvas canvas = new ImageCanvas(img); + canvas.setBackground(Color.BLUE); + + Frame frame = new Frame("CopyAnimatedGIFTest"); + frame.setSize(400, 200); + frame.add(canvas); + frame.setVisible(true); + } + + private void copyImage() { + Clipboard sys = Toolkit.getDefaultToolkit().getSystemClipboard(); + sys.setContents(new MyTransferable(img), null); + } + + private void runTest(boolean isImageDisplayed) throws Exception { + + if (isImageDisplayed) { + Robot robot = new Robot(); + EventQueue.invokeAndWait(this::createGUI); + robot.waitForIdle(); + robot.delay(1000); + } + + EventQueue.invokeLater(() -> { + copyImage(); + latch.countDown(); + }); + + if (!latch.await(TIMEOUT, MILLISECONDS)) { + String str = isImageDisplayed ? " displayed":" not displayed"; + throw new RuntimeException("Image copying taking too long for image" + + str + " case"); + } + } + + public static void main(String[] args) throws Exception { + // run test with Image showing up on screen + new CopyAnimatedGIFTest().runTest(true); + + // run test without Image showing up + new CopyAnimatedGIFTest().runTest(false); + } + + private static class ImageCanvas extends Canvas { + private final Image img; + public ImageCanvas(Image img) { + this.img = img; + } + + @Override + public void paint(Graphics g) { + g.drawImage(img, 0, 0, getWidth(), getHeight(), this); + } + } + + private static class MyTransferable implements Transferable { + private final Image img; + private final DataFlavor[] flavors = {DataFlavor.imageFlavor}; + + public MyTransferable(Image img) { + this.img = img; + } + + @Override + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + @Override + public boolean isDataFlavorSupported(DataFlavor flavor) { + return flavors[0].equals(flavor); + } + + @Override + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + return img; + } + } + +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Component/ComponentRedrawnTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Component/ComponentRedrawnTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Component/ComponentRedrawnTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Component/ComponentRedrawnTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,198 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8139581 + * @summary Verify that components are redrawn after + * removal and addition to a container + * @run main ComponentRedrawnTest + */ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.swing.JButton; + +public class ComponentRedrawnTest { + + private static Frame frame; + private static Panel componentPanel; + private static Button buttonRemove; + private static Button buttonAdd; + private static Button awtButton; + + private static volatile Robot robot; + private static volatile int x; + private static volatile int y; + private static AtomicInteger awtPainted = new AtomicInteger(); + private static AtomicInteger swingPainted = new AtomicInteger(); + + public static void main(String args[]) throws Exception { + try { + EventQueue.invokeAndWait(() -> createGUI()); + runTest(); + System.out.println("Test Passed"); + } finally { + EventQueue.invokeAndWait(() -> dispose()); + } + } + + private static void createGUI() { + frame = new Frame("ComponentRedrawnTest"); + frame.setSize(350, 300); + frame.setBackground(Color.red); + + componentPanel = new Panel(); + componentPanel.setLayout(null); + componentPanel.setBackground(Color.green); + + awtButton = new Button("AWT Button") { + @Override + public void paint(Graphics g) { + super.paint(g); + awtPainted.incrementAndGet(); + } + }; + + awtButton.setBounds(0, 0, 330, 100); + componentPanel.add(awtButton); + + JButton swingButton = new JButton("Swing JButton") { + @Override + public void paint(Graphics g) { + super.paint(g); + swingPainted.incrementAndGet(); + } + }; + + swingButton.setBounds(0, 100, 330, 100); + componentPanel.add(swingButton); + frame.add(componentPanel, BorderLayout.CENTER); + buttonRemove = new Button("remove"); + buttonRemove.addActionListener(ae -> buttonClicked(ae)); + + buttonAdd = new Button("add"); + buttonAdd.addActionListener(ae -> buttonClicked(ae)); + + Panel controlPanel = new Panel(); + controlPanel.setLayout(new BorderLayout()); + controlPanel.add(buttonRemove, BorderLayout.NORTH); + controlPanel.add(buttonAdd, BorderLayout.SOUTH); + + frame.add(controlPanel, BorderLayout.SOUTH); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void buttonClicked(ActionEvent ae) { + if (ae.getSource() == buttonRemove) { + frame.remove(componentPanel); + } else if (ae.getSource() == buttonAdd) { + frame.add(componentPanel); + } + frame.invalidate(); + frame.validate(); + } + + private static void runTest() throws Exception { + EventQueue.invokeAndWait(() -> createGUI()); + robot = new Robot(); + robot.setAutoDelay(500); + awtPainted.set(0); + swingPainted.set(0); + + try { + EventQueue.invokeAndWait(() -> { + x = awtButton.getLocationOnScreen().x + + awtButton.getSize().width / 2; + y = awtButton.getLocationOnScreen().y + + awtButton.getSize().height / 2; + }); + } catch (Exception e) { + throw new RuntimeException("Unexpected Exception encountered: " + e); + } + + robot.mouseMove(x, y); + robot.waitForIdle(); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK); + + try { + EventQueue.invokeAndWait(() -> { + x = buttonRemove.getLocationOnScreen().x + + buttonRemove.getSize().width / 2; + y = buttonRemove.getLocationOnScreen().y + + buttonRemove.getSize().height / 2; + }); + } catch (Exception e) { + throw new RuntimeException("Unexpected Exception encountered: " + e); + } + + robot.mouseMove(x, y); + robot.waitForIdle(); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK); + + try { + EventQueue.invokeAndWait(() -> { + x = buttonAdd.getLocationOnScreen().x + + buttonAdd.getSize().width / 2; + y = buttonAdd.getLocationOnScreen().y + + buttonAdd.getSize().height / 2; + }); + + } catch (Exception e) { + throw new RuntimeException("Unexpected Exception encountered: " + e); + } + robot.mouseMove(x, y); + robot.waitForIdle(); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK); + + if (awtPainted.get() == 0) { + throw new RuntimeException("AWT button is not painted"); + } + if (swingPainted.get() == 0) { + throw new RuntimeException("Swing button is not painted"); + } + } + + private static void dispose() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/CRLFTest/CRLFTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,209 @@ +/* + * 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 4914613 + @summary tests that "\r\n" is not converted to "\r\r\n" + @key headful +*/ + +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.SystemFlavorMap; +import java.awt.datatransfer.Transferable; +import java.io.File; +import java.io.InputStream; + +public class CRLFTest { + private int returnCode = 0; + + public static void main(String[] args) { + CRLFTest parent = new CRLFTest(); + parent.start(); + } + public void start() { + + try { + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + + System.getProperty("test.classes", ".") + + " CRLFTestClipboard"; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + returnCode = pres.exitValue; + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + System.err.println("Child return code=" + returnCode); + } catch (Throwable e) { + e.printStackTrace(); + } + } +} + +class CRLFTestClipboard implements ClipboardOwner { + private static final Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + + public static void main(String[] args) { + CRLFTestClipboard child = new CRLFTestClipboard(); + child.run(); + } + + public void run() { + ClipboardOwner owner = new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, + Transferable contents) { + System.exit(0); + } + }; + clipboard.setContents(new StringSelection("\r\n"), owner); + + // Wait to let the parent retrieve the contents. + try { + Thread.sleep(30000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void lostOwnership(Clipboard clip, Transferable contents) { + final DataFlavor df = + new DataFlavor("text/test-subtype; class=java.io.InputStream", + null); + SystemFlavorMap sfm = + (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap(); + sfm.addUnencodedNativeForFlavor(df, "TEXT"); + sfm.addFlavorForUnencodedNative("TEXT", df); + Runnable r = new Runnable() { + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Transferable t = clipboard.getContents(null); + boolean passed = true; + try { + InputStream is = + (InputStream)t.getTransferData(df); + int prev = 0; + int b = 0; + System.err.print("Bytes: "); + while ((b = is.read()) != -1) { + System.err.print(" " + Integer. + toHexString((int)b & 0xFF)); + if (b == 0xD && prev == 0xD) { + passed = false; + } + prev = b; + } + System.err.println(); + } catch (Exception e) { + e.printStackTrace(); + } + clipboard.setContents(new StringSelection(""), null); + + if (!passed) { + throw new RuntimeException("Test failed"); + } + } + }; + new Thread(r).start(); + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/DataConversionDeadlockTest/DataConversionDeadlockTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,204 @@ +/* + * 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 4760364 + @summary Tests that the deadlock doesn't happen when two apps request + selection data from each other. + @key headful +*/ + +import java.awt.EventQueue; +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.io.File; +import java.io.IOException; +import java.io.InputStream; + +public class DataConversionDeadlockTest { + + public static void main(String[] args) { + DataConversionDeadlockTest parent = new DataConversionDeadlockTest(); + parent.start(); + } + + public void start() { + try { + String javaPath = System.getProperty("java.home", ""); + String cmd = javaPath + File.separator + "bin" + + File.separator + "java -cp " + + System.getProperty("test.classes", ".") + + " DataConversionDeadlockTestChild"; + + Process process = Runtime.getRuntime().exec(cmd); + ProcessResults pres = ProcessResults.doWaitFor(process); + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} + +class DataConversionDeadlockTestChild implements ClipboardOwner, Runnable { + private static final Toolkit toolkit = Toolkit.getDefaultToolkit(); + private static final Clipboard clipboard = toolkit.getSystemClipboard(); + private static final Clipboard selection = toolkit.getSystemSelection(); + private static final Transferable t = new StringSelection("TEXT"); + + public void lostOwnership(Clipboard cb, Transferable contents) { + ClipboardUtil.setClipboardContents(selection, t, this); + new Thread(this).start(); + } + + public void run() { + for (int i = 0; i < 100; i++) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ClipboardUtil.getClipboardContents(clipboard, null); + } + }); + } + } + + public static void main(String[] args) { + if (clipboard == null || selection == null) { + return; + } + ClipboardUtil.setClipboardContents(clipboard, t, null); + for (int i = 0; i < 100; i++) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ClipboardUtil.getClipboardContents(selection, null); + } + }); + } + } +} + +class ClipboardUtil { + public 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 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(); } + } + } + } + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/DataFlavor/BestTextFlavorTest/BestTextFlavorTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 To test if the DataFlavor.selectBestTextFlavor() method + is selecting the correct best flavor from an array of flavors. +*/ + + +import java.awt.datatransfer.DataFlavor; +import java.util.Vector; + +public class BestTextFlavorTest { + public static DataFlavor plainISOFlavor, + plainAsciiFlavor, + plainTextFlavor, + enrichFlavor; + public static DataFlavor[] bestFlavorArray1; + public static DataFlavor[] bestFlavorArray2; + public static DataFlavor bestFlavor1,bestFlavor2; + private static Vector tmpFlavors; + + //Creating new flavors + static { + + tmpFlavors = new Vector(); + try { + tmpFlavors.addElement(DataFlavor.stringFlavor); + tmpFlavors.addElement(new DataFlavor + ("text/plain; charset=unicode")); + tmpFlavors.addElement( + new DataFlavor("text/plain; charset=us-ascii")); + enrichFlavor=new DataFlavor("text/enriched; charset=ascii"); + tmpFlavors.addElement(enrichFlavor); + plainTextFlavor=DataFlavor.getTextPlainUnicodeFlavor(); + tmpFlavors.addElement(plainTextFlavor); + plainAsciiFlavor=new DataFlavor("text/plain; charset=ascii"); + tmpFlavors.addElement(plainAsciiFlavor); + plainISOFlavor=new DataFlavor("text/plain; charset=iso8859-1"); + tmpFlavors.addElement(plainISOFlavor); + } + catch (ClassNotFoundException e) { + // should never happen... + System.out.println("ClassNotFound Exception is thrown when"+ + "flavors are created"); + } + } + + public static void main(String[] args) { + bestFlavorArray1 = new DataFlavor[tmpFlavors.size()]; + tmpFlavors.copyInto(bestFlavorArray1); + + //Selecting the best text flavor from a set of Data Flavors. + bestFlavor1 = DataFlavor.selectBestTextFlavor(bestFlavorArray1); + System.out.println("The Best Text Flavor is " + bestFlavor1); + + bestFlavorArray2 = reverseDataFlavor(bestFlavorArray1); + bestFlavor2 = DataFlavor.selectBestTextFlavor(bestFlavorArray2); + System.out.println("The Best Text Flavor is " + bestFlavor2); + + //Checking whether the selected flavors in both the arrays are same. + if (bestFlavor2.match(bestFlavor1)) { + System.out.println("The test is Passed"); + } + else { + System.out.println("The test is Failed"); + throw new RuntimeException("SelectBestTextFlavor doesn't return "+ + "the same best Text flavor from a set of DataFlavors, "+ + "it always returns the first Text Flavor encountered."); + } + } + + //Returns the array of DataFlavor passed in reverse order. + public static DataFlavor[] reverseDataFlavor(DataFlavor[] dataflavor) { + + DataFlavor[] tempFlavor = new DataFlavor[dataflavor.length]; + int j = 0; + for (int i = dataflavor.length - 1 ; i >= 0; i--) { + tempFlavor[j] = dataflavor[i]; + j++; + } + return tempFlavor; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/datatransfer/FileTransferAWTLockTest/FileTransferAWTLockTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,219 @@ +/* + * 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 4916420 + @requires os.family == "linux" + @summary verifies that AWT_LOCK is properly taken during file transfer + @key headful +*/ + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + +public class FileTransferAWTLockTest { + + public static void main(String[] args) { + if (!(System.getProperty("os.name").startsWith("Linux"))) { + return; + } + FileTransferAWTLockTest parent = new FileTransferAWTLockTest(); + parent.start(); + } + + public void start() { + String stderr = null; + try { + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + + System.getProperty("test.classes", ".") + + " -Dawt.toolkit=sun.awt.X11.XToolkit" + + " FileTransferAWTLockTestChild"; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + + stderr = pres.stderr; + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + System.err.println("======================================"); + } + + System.err.println("Child VM return code: " + pres.exitValue); + } catch (Throwable e) { + e.printStackTrace(); + } + + if (stderr != null && stderr.indexOf("InternalError") >= 0) { + throw new RuntimeException("Test failed"); + } + } +} + +class FileTransferAWTLockTestChild { + static final Clipboard clipboard = + Toolkit.getDefaultToolkit().getSystemClipboard(); + static final Transferable transferable = new Transferable() { + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { DataFlavor.javaFileListFlavor }; + } + public boolean isDataFlavorSupported(DataFlavor df) { + return DataFlavor.javaFileListFlavor.equals(df); + } + public Object getTransferData(DataFlavor df) + throws IOException, UnsupportedFlavorException { + if (!isDataFlavorSupported(df)) { + throw new UnsupportedFlavorException(df); + } + + File file = new File("file.txt"); + ArrayList list = new ArrayList(); + list.add(file); + return list; + } + }; + + public static void main(String[] args) { + Util.setClipboardContents(clipboard, transferable, null); + FileTransferAWTLockTestChild test = new FileTransferAWTLockTestChild(); + test.run(); + } + + public void run() { + Transferable t = Util.getClipboardContents(clipboard, null); + try { + t.getTransferData(DataFlavor.javaFileListFlavor); + } catch (Exception e) { + e.printStackTrace(); + } + } +} + +class Util { + public static void setClipboardContents(Clipboard cb, + Transferable contents, + ClipboardOwner owner) { + synchronized (cb) { + while (true) { + try { + cb.setContents(contents, owner); + return; + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } + + public static Transferable getClipboardContents(Clipboard cb, + Object requestor) { + synchronized (cb) { + while (true) { + try { + return cb.getContents(requestor); + } catch (IllegalStateException ise) { + try { Thread.sleep(100); } + catch (InterruptedException e) { e.printStackTrace(); } + } + } + } + } +} + +class ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/MouseExitGestureTriggerTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,127 @@ +/* + * 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.JFrame; +import javax.swing.JPanel; +import javax.swing.JTree; +import java.awt.EventQueue; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.event.InputEvent; + +/* + @test + @bug 4273712 4396746 + @summary tests that mouse exit event doesn't trigger drag + @key headful + @run main MouseExitGestureTriggerTest +*/ + +public class MouseExitGestureTriggerTest { + + boolean recognized = false; + volatile JFrame frame; + volatile JPanel panel; + volatile JTree tree; + volatile DragSource dragSource; + volatile Point srcPoint; + volatile Rectangle r; + volatile DragGestureListener dgl; + static final int FRAME_ACTIVATION_TIMEOUT = 2000; + static final int RECOGNITION_TIMEOUT = 1000; + + public static void main(String[] args) throws Exception { + MouseExitGestureTriggerTest test = new MouseExitGestureTriggerTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + + public void init() { + frame = new JFrame("MouseExitGestureTriggerTest"); + panel = new JPanel(); + tree = new JTree(); + + dragSource = DragSource.getDefaultDragSource(); + dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + Thread.dumpStack(); + recognized = true; + } + }; + + tree.setEditable(true); + dragSource.createDefaultDragGestureRecognizer(tree, + DnDConstants.ACTION_MOVE, + dgl); + panel.add(tree); + frame.getContentPane().add(panel); + frame.setLocation(200, 200); + + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + final Robot robot = new Robot(); + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + clickRootNode(robot); + clickRootNode(robot); + clickRootNode(robot); + + Thread.sleep(RECOGNITION_TIMEOUT); + + EventQueue.invokeAndWait(() -> { + if (recognized) { + throw new RuntimeException("Mouse exit event triggered drag"); + } + }); + } + + void clickRootNode(final Robot robot) throws Exception { + EventQueue.invokeAndWait(() -> { + srcPoint = tree.getLocationOnScreen(); + r = tree.getRowBounds(0); + }); + srcPoint.translate(r.x + 2 * r.width /3 , r.y + r.height / 2); + robot.mouseMove(srcPoint.x ,srcPoint.y); + + robot.mousePress(InputEvent.BUTTON1_MASK); + Thread.sleep(10); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + Thread.sleep(10); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/MozillaDnDTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/MozillaDnDTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/MozillaDnDTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/MozillaDnDTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,494 @@ +/* + * 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 java.awt.AWTEvent; +import java.awt.Component; +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.Robot; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.SystemFlavorMap; +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.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceDropEvent; +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.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/* + @test + @bug 4746177 + @summary tests that data types exported by Netscape 6.2 are supported + @requires (os.family != "windows") + @key headful + @run main MozillaDnDTest +*/ + +public class MozillaDnDTest { + + public static final int CODE_NOT_RETURNED = -1; + public static final int CODE_OK = 0; + public static final int CODE_FAILURE = 1; + public static final String DATA = "www.sun.com"; + + private int returnCode = CODE_NOT_RETURNED; + + volatile Frame frame; + volatile Robot robot; + volatile Panel panel; + volatile Point p; + volatile Dimension d; + + public static void main(String[] args) throws Exception { + MozillaDnDTest test = new MozillaDnDTest(); + if (args.length > 0) { + test.run(args); + } else { + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + } + + public void run(String[] args) { + 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]); + + panel = new DragSourcePanel(); + frame = new Frame(); + + 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)) { + System.err.println("WARNING: Couldn't locate " + panel + + " at point " + sourcePoint); + System.exit(MozillaDnDTest.CODE_OK); + } + + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_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(50); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + } catch (Throwable e) { + e.printStackTrace(); + System.exit(MozillaDnDTest.CODE_FAILURE); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void init() { + frame = new Frame(); + panel = new DropTargetPanel(); + + frame.setTitle("DropTarget frame"); + frame.setLocation(10, 200); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + } + + public void start() { + // Solaris/Linux-only test + if (System.getProperty("os.name").startsWith("Windows")) { + return; + } + try { + Util.waitForInit(); + EventQueue.invokeAndWait(() -> { + p = panel.getLocationOnScreen(); + d = panel.getSize(); + }); + + Robot robot = new Robot(); + Point pp = new Point(p); + pp.translate(d.width / 2, d.height / 2); + if (!Util.pointInComponent(robot, pp, panel)) { + System.err.println("WARNING: Couldn't locate " + panel + + " at point " + pp); + return; + } + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + System.getProperty("test.classes", ".") + + " MozillaDnDTest " + + p.x + " " + p.y + " " + d.width + " " + d.height; + + Process process = Runtime.getRuntime().exec(command); + ProcessResults pres = ProcessResults.doWaitFor(process); + returnCode = pres.exitValue; + + if (pres.stderr != null && pres.stderr.length() > 0) { + System.err.println("========= Child VM System.err ========"); + System.err.print(pres.stderr); + System.err.println("======================================"); + } + + if (pres.stdout != null && pres.stdout.length() > 0) { + System.err.println("========= Child VM System.out ========"); + System.err.print(pres.stdout); + 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."); + } + } +} + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + public 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_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_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 ProcessResults { + public int exitValue; + public String stdout; + public String stderr; + + public ProcessResults() { + exitValue = -1; + stdout = ""; + stderr = ""; + } + + /** + * Method to perform a "wait" for a process and return its exit value. + * This is a workaround for Process.waitFor() never returning. + */ + public static ProcessResults doWaitFor(Process p) { + ProcessResults pres = new ProcessResults(); + + InputStream in = null; + InputStream err = null; + + try { + in = p.getInputStream(); + err = p.getErrorStream(); + + boolean finished = false; + + while (!finished) { + try { + while (in.available() > 0) { + pres.stdout += (char)in.read(); + } + while (err.available() > 0) { + pres.stderr += (char)err.read(); + } + // Ask the process for its exitValue. If the process + // is not finished, an IllegalThreadStateException + // is thrown. If it is finished, we fall through and + // the variable finished is set to true. + pres.exitValue = p.exitValue(); + finished = true; + } + catch (IllegalThreadStateException e) { + // Process is not finished yet; + // Sleep a little to save on CPU cycles + Thread.currentThread().sleep(500); + } + } + if (in != null) in.close(); + if (err != null) err.close(); + } + catch (Throwable e) { + System.err.println("doWaitFor(): unexpected exception"); + e.printStackTrace(); + } + return pres; + } +} + +class DragSourcePanel extends Panel { + static final Dimension preferredDimension = new Dimension(200, 200); + static final DataFlavor df = new DataFlavor("application/mozilla-test-flavor", + null); + final DragSource ds = DragSource.getDefaultDragSource(); + final Transferable t = new Transferable() { + final DataFlavor[] flavors = new DataFlavor[] { df }; + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + public boolean isDataFlavorSupported(DataFlavor flav) { + return df.equals(flav); + } + public Object getTransferData(DataFlavor flav) + throws IOException, UnsupportedFlavorException { + if (!isDataFlavorSupported(flav)) { + throw new UnsupportedFlavorException(flav); + } + byte[] bytes = MozillaDnDTest.DATA.getBytes("ASCII"); + return new ByteArrayInputStream(bytes); + } + }; + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragDropEnd(DragSourceDropEvent dsde) { + System.exit(MozillaDnDTest.CODE_OK); + } + }; + final DragGestureListener dgl = new DragGestureListener() { + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, t, dsl); + } + }; + final DragGestureRecognizer dgr = + ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, + dgl); + static { + SystemFlavorMap sfm = + (SystemFlavorMap)SystemFlavorMap.getDefaultFlavorMap(); + String[] natives = new String[] { + "_NETSCAPE_URL", + "text/plain", + "text/unicode", + "text/x-moz-url", + "text/html" + }; + sfm.setNativesForFlavor(df, natives); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 200); + final DropTarget dt = new DropTarget(this, this); + + 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); + } + + public String getTransferString(Transferable t) { + String string = null; + DataFlavor[] dfs = t.getTransferDataFlavors(); + for (int i = 0; i < dfs.length; i++) { + if ("text".equals(dfs[i].getPrimaryType()) || + DataFlavor.stringFlavor.equals(dfs[i])) { + try { + Object o = t.getTransferData(dfs[i]); + if (o instanceof InputStream || + o instanceof Reader) { + Reader reader = null; + if (o instanceof InputStream) { + InputStream is = (InputStream)o; + reader = new InputStreamReader(is); + } else { + reader = (Reader)o; + } + StringBuffer buf = new StringBuffer(); + for (int c = reader.read(); c != -1; c = reader.read()) { + buf.append((char)c); + } + reader.close(); + string = buf.toString(); + break; + } else if (o instanceof String) { + string = (String)o; + break; + } + } catch (Exception e) { + // ignore. + } + } + } + return string; + } + + 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; + } + + Transferable t = dtde.getTransferable(); + String str = getTransferString(t); + dtde.dropComplete(true); + + if (!MozillaDnDTest.DATA.equals(str)) { + throw new RuntimeException("Drop data:" + str); + } + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/MultiDataFlavorDropTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,415 @@ +/* + * 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. + */ + +import java.awt.Button; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.List; +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.File; +import java.io.InputStream; +import java.io.Serializable; + +/* + @test + @bug 4399700 + @summary tests that drop transfer data can be requested in several data flavors. + @key headful + @run main MultiDataFlavorDropTest +*/ + +public class MultiDataFlavorDropTest { + + public static final int CODE_NOT_RETURNED = -1; + public static final int CODE_OK = 0; + public static final int CODE_FAILURE = 1; + public static final int FRAME_ACTIVATION_TIMEOUT = 2000; + public static final int DROP_TIMEOUT = 10000; + public static final int DROP_COMPLETION_TIMEOUT = 1000; + + private int returnCode = CODE_NOT_RETURNED; + + volatile Frame frame; + volatile Robot robot; + volatile Panel panel; + volatile Point p; + volatile Dimension d; + + public static void main(String[] args) throws Exception { + MultiDataFlavorDropTest test = new MultiDataFlavorDropTest(); + if (args.length > 0) { + test.run(args); + } else { + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + } + + public void run(String[] args) { + 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 TransferableNumber(); + panel = new DragSourcePanel(t); + + frame = new Frame(); + frame.setTitle("DragSource frame"); + frame.setLocation(300, 200); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + 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(); + robot.mouseMove(sourcePoint.x, sourcePoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_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_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + synchronized (t) { + t.wait(DROP_TIMEOUT); + } + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + + } catch (Throwable e) { + e.printStackTrace(); + System.exit(MultiDataFlavorDropTest.CODE_FAILURE); + } + System.exit(MultiDataFlavorDropTest.CODE_OK); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void init() { + frame = new Frame(); + panel = new DropTargetPanel(); + + frame.setTitle("MultiDataFlavorDropTest"); + frame.setLocation(10, 200); + frame.add(panel); + + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + EventQueue.invokeAndWait(() -> { + p = panel.getLocationOnScreen(); + d = panel.getSize(); + }); + + String javaPath = System.getProperty("java.home", ""); + String command = javaPath + File.separator + "bin" + + File.separator + "java -cp " + System.getProperty("test.classes", ".") + + " MultiDataFlavorDropTest " + + 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("======================================"); + } + + 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."); + } + } +} + +class DragSourceButton extends Button implements Serializable, + DragGestureListener, + DragSourceListener { + + 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) {} + + public void dragDropEnd(DragSourceDropEvent dsde) {} + + public void dropActionChanged(DragSourceDragEvent dsde) {} +} + +class IntegerDataFlavor extends DataFlavor { + + private final int number; + + public IntegerDataFlavor(int n) throws ClassNotFoundException { + super("application/integer-" + n + + "; class=java.lang.Integer"); + this.number = n; + } + + public int getNumber() { + return number; + } +} + +class TransferableNumber implements Transferable { + + private int transferDataRequestCount = 0; + public static final int NUM_DATA_FLAVORS = 5; + static final DataFlavor[] supportedFlavors = + new DataFlavor[NUM_DATA_FLAVORS]; + + static { + try { + for (int i = 0; i < NUM_DATA_FLAVORS; i++) { + supportedFlavors[i] = + new IntegerDataFlavor(i); + } + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public DataFlavor[] getTransferDataFlavors() { + return supportedFlavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + if (flavor instanceof IntegerDataFlavor) { + IntegerDataFlavor integerFlavor = (IntegerDataFlavor)flavor; + int flavorNumber = integerFlavor.getNumber(); + if (flavorNumber >= 0 && flavorNumber < NUM_DATA_FLAVORS) { + return true; + } + } + return false; + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException { + + if (!isDataFlavorSupported(flavor)) { + throw new UnsupportedFlavorException(flavor); + } + + transferDataRequestCount++; + + if (transferDataRequestCount >= NUM_DATA_FLAVORS) { + synchronized (this) { + this.notifyAll(); + } + } + + IntegerDataFlavor integerFlavor = (IntegerDataFlavor)flavor; + return new Integer(integerFlavor.getNumber()); + } +} + +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 { + + 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); + } + + 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(); + + if (dfs.length != TransferableNumber.NUM_DATA_FLAVORS) { + throw new RuntimeException("FAILED: Incorrect number of data flavors."); + } + + for (int i = 0; i < dfs.length; i++) { + + DataFlavor flavor = dfs[i]; + Integer transferNumber = null; + + if (flavor.getRepresentationClass().equals(Integer.class)) { + try { + transferNumber = (Integer)t.getTransferData(flavor); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("FAILED: Cannot get data: " + + flavor.getMimeType()); + } + } + + boolean supportedFlavor = false; + for (int j = 0; j < TransferableNumber.NUM_DATA_FLAVORS; j++) { + int number = (i + j) % TransferableNumber.NUM_DATA_FLAVORS; + try { + if (flavor.equals(new IntegerDataFlavor(number))) { + if (!(new Integer(number).equals(transferNumber))) { + throw new RuntimeException("FAILED: Invalid data \n" + + "\tflavor : " + flavor + + "\tdata : " + transferNumber); + } + supportedFlavor = true; + break; + } + } catch (ClassNotFoundException cannotHappen) { + } + } + if (!supportedFlavor) { + throw new RuntimeException("FAILED: Invalid flavor: " + flavor); + } + + list.add(transferNumber + ":" + flavor.getMimeType()); + } + + dtc.dropComplete(true); + validate(); + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NativeDragJavaDropTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,152 @@ +/* + * 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. + */ + +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Point; +import java.awt.Robot; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +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.awt.event.InputEvent; + +/* + @test + @bug 4399700 + @summary tests that Motif drag support for label widget doesn't cause + crash when used for drag and drop from label to Java drop target + @key headful + @run main NativeDragJavaDropTest +*/ + +public class NativeDragJavaDropTest { + + volatile Frame frame; + volatile DropTargetLabel label; + volatile Point p; + volatile Dimension d; + public static final int FRAME_ACTIVATION_TIMEOUT = 1000; + public static final int DRAG_START_TIMEOUT = 500; + public static final int DROP_COMPLETION_TIMEOUT = 2000; + + public static void main(String[] args) throws Exception { + NativeDragJavaDropTest test = new NativeDragJavaDropTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + + public void init() { + frame = new Frame(); + label = new DropTargetLabel(); + frame.setTitle("NativeDragJavaDropTest"); + frame.setLocation(200, 200); + frame.add(label); + + frame.pack(); + frame.setVisible(true); + } + + public void start() throws Exception { + Robot robot = new Robot(); + robot.waitForIdle(); + Thread.sleep(FRAME_ACTIVATION_TIMEOUT); + + EventQueue.invokeAndWait(() -> { + p = label.getLocationOnScreen(); + d = label.getSize(); + }); + + p.translate(d.width / 2, d.height / 2); + + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON2_MASK); + + Thread.sleep(DRAG_START_TIMEOUT); + + robot.mouseRelease(InputEvent.BUTTON2_MASK); + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + } +} + +class DropTargetLabel extends Label implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + + public DropTargetLabel() { + super("Label"); + 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(); + + if (dfs != null && dfs.length >= 1) { + Transferable transfer = dtde.getTransferable(); + + try { + Object obj = (Object)transfer.getTransferData(dfs[0]); + } catch (Throwable e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } + dtc.dropComplete(true); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NestedHeavyweightDropTargetTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,492 @@ +/* + * 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. + */ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +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.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.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +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 4389284 + @summary tests that drop targets registered on nested heavyweight + components work properly + @key headful + @run main NestedHeavyweightDropTargetTest +*/ + +public class NestedHeavyweightDropTargetTest { + + volatile Frame frame; + volatile DragSourceButton dragSourceButton; + volatile DropTargetPanel dropTargetPanel; + volatile InnerDropTargetPanel innerDropTargetPanel; + volatile Button button; + volatile Dimension d; + volatile Point srcPoint; + volatile Point dstPoint; + + static final int DROP_COMPLETION_TIMEOUT = 1000; + + public static void main(String[] args) throws Exception { + NestedHeavyweightDropTargetTest test = new NestedHeavyweightDropTargetTest(); + EventQueue.invokeAndWait(test::init); + try { + test.start(); + } finally { + EventQueue.invokeAndWait(() -> { + if (test.frame != null) { + test.frame.dispose(); + } + }); + } + } + + public void init() { + frame = new Frame(); + dragSourceButton = new DragSourceButton(); + dropTargetPanel = new DropTargetPanel(); + innerDropTargetPanel = new InnerDropTargetPanel(); + button = new Button("button"); + button.setBackground(Color.red); + + innerDropTargetPanel.setLayout(new GridLayout(3, 1)); + innerDropTargetPanel.add(button); + innerDropTargetPanel.setBackground(Color.yellow); + + dropTargetPanel.setLayout(new GridLayout(2, 1)); + dropTargetPanel.add(innerDropTargetPanel); + dropTargetPanel.setBackground(Color.green); + + frame.setTitle("NestedHeavyweightDropTargetTest"); + frame.setLocation(200, 200); + frame.setLayout(new BorderLayout()); + frame.add(dropTargetPanel, BorderLayout.CENTER); + frame.add(dragSourceButton, BorderLayout.SOUTH); + + frame.pack(); + + innerDropTargetPanel.setDropTarget(new DropTarget(innerDropTargetPanel, innerDropTargetPanel)); + dropTargetPanel.setDropTarget(new DropTarget(dropTargetPanel, dropTargetPanel)); + + frame.setVisible(true); + } + + public void start() throws Exception { + Robot robot = new Robot(); + Util.waitForInit(); + + test1(robot); + test2(robot); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public void test1(Robot robot) throws Exception { + innerDropTargetPanel.setDragEnterTriggered(false); + innerDropTargetPanel.setDragOverTriggered(false); + innerDropTargetPanel.setDragExitTriggered(false); + innerDropTargetPanel.setDropTriggered(false); + + EventQueue.invokeAndWait(() -> { + srcPoint = dragSourceButton.getLocationOnScreen(); + d = dragSourceButton.getSize(); + }); + + srcPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, srcPoint, dragSourceButton)) { + System.err.println("WARNING: Couldn't locate " + dragSourceButton + + " at point " + srcPoint); + return; + } + + EventQueue.invokeAndWait(() -> { + dstPoint = innerDropTargetPanel.getLocationOnScreen(); + d = innerDropTargetPanel.getSize(); + }); + + dstPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, dstPoint, innerDropTargetPanel)) { + System.err.println("WARNING: Couldn't locate " + innerDropTargetPanel + + " at point " + dstPoint); + return; + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + + if (!innerDropTargetPanel.isDragEnterTriggered()) { + throw new RuntimeException("child dragEnter() not triggered"); + } + + if (!innerDropTargetPanel.isDragOverTriggered()) { + throw new RuntimeException("child dragOver() not triggered"); + } + + if (!innerDropTargetPanel.isDropTriggered()) { + throw new RuntimeException("child drop() not triggered"); + } + } + + public void test2(Robot robot) throws Exception { + innerDropTargetPanel.setDragEnterTriggered(false); + innerDropTargetPanel.setDragOverTriggered(false); + innerDropTargetPanel.setDragExitTriggered(false); + innerDropTargetPanel.setDropTriggered(false); + + EventQueue.invokeAndWait(() -> { + srcPoint = dragSourceButton.getLocationOnScreen(); + d = dragSourceButton.getSize(); + }); + srcPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, srcPoint, dragSourceButton)) { + System.err.println("WARNING: Couldn't locate " + dragSourceButton + + " at point " + srcPoint); + return; + } + + EventQueue.invokeAndWait(() -> { + dstPoint = button.getLocationOnScreen(); + d = button.getSize(); + }); + + dstPoint.translate(d.width / 2, d.height / 2); + + if (!Util.pointInComponent(robot, dstPoint, button)) { + System.err.println("WARNING: Couldn't locate " + button + + " at point " + dstPoint); + return; + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_MASK); + for (;!srcPoint.equals(dstPoint); + srcPoint.translate(sign(dstPoint.x - srcPoint.x), + sign(dstPoint.y - srcPoint.y))) { + robot.mouseMove(srcPoint.x, srcPoint.y); + Thread.sleep(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.keyRelease(KeyEvent.VK_CONTROL); + + Thread.sleep(DROP_COMPLETION_TIMEOUT); + + if (!innerDropTargetPanel.isDragEnterTriggered()) { + throw new RuntimeException("child dragEnter() not triggered"); + } + + if (!innerDropTargetPanel.isDragOverTriggered()) { + throw new RuntimeException("child dragOver() not triggered"); + } + + if (!innerDropTargetPanel.isDropTriggered()) { + throw new RuntimeException("child drop() not triggered"); + } + } +} + +class Util implements AWTEventListener { + private static final Toolkit tk = Toolkit.getDefaultToolkit(); + public 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_MASK); + synchronized (SYNC_LOCK) { + robot.mouseRelease(InputEvent.BUTTON1_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, + 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 = null; + + 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 InnerDropTargetPanel extends DropTargetPanel { + private boolean dragEnterTriggered = false; + private boolean dragOverTriggered = false; + private boolean dragExitTriggered = false; + private boolean dropTriggered = false; + + public void dragEnter(DropTargetDragEvent dtde) { + setDragEnterTriggered(true); + } + + public void dragExit(DropTargetEvent dte) { + setDragExitTriggered(true); + } + + public void dragOver(DropTargetDragEvent dtde) { + setDragOverTriggered(true); + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + setDropTriggered(true); + dtde.rejectDrop(); + } + + public boolean isDragEnterTriggered() { + return dragEnterTriggered; + } + + public boolean isDragOverTriggered() { + return dragOverTriggered; + } + + public boolean isDragExitTriggered() { + return dragExitTriggered; + } + + public boolean isDropTriggered() { + return dropTriggered; + } + + public void setDragEnterTriggered(boolean b) { + dragEnterTriggered = b; + } + + public void setDragOverTriggered(boolean b) { + dragOverTriggered = b; + } + + public void setDragExitTriggered(boolean b) { + dragExitTriggered = b; + } + + public void setDropTriggered(boolean b) { + dropTriggered = b; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + 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 -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NextDropActionTest/NextDropActionTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,203 @@ +/* + * 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 4887150 + @summary tests that after performing COPY drop, MOVE drop can be performed too + @key headful + @run main NextDropActionTest +*/ + +import java.awt.AWTException; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +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.DragSourceDropEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + + +public class NextDropActionTest { + private final long WAIT_TIMEOUT = 30000; + private volatile boolean failed; + private volatile boolean firstEnd; + private volatile boolean secondEnd; + private final Object LOCK = new Object(); + private Frame frame; + private Panel panel; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NextDropActionTest nextDropActionTest = new NextDropActionTest(); + nextDropActionTest.start(); + } + + public void start() throws InterruptedException, + InvocationTargetException, AWTException { + + EventQueue.invokeAndWait(() -> { + panel = new Panel(); + frame = new Frame("NextDropActionTest"); + frame.add(panel); + frame.setBounds(300, 300, 300, 300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + }); + + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + final DragSourceListener dsl = new DragSourceAdapter() { + boolean firstCall = true; + public void dragDropEnd(DragSourceDropEvent e) { + System.err.println("DragSourseListener.dragDropEnd(): " + + " firstCall=" + firstCall + + " drop action=" + e.getDropAction()); + if (firstCall) { + firstCall = false; + synchronized (LOCK) { + firstEnd = true; + LOCK.notifyAll(); + } + return; + } + if (e.getDropAction() != DnDConstants.ACTION_MOVE) { + System.err.println("FAILURE: wrong drop action:" + + e.getDropAction()); + failed = true; + } + synchronized (LOCK) { + secondEnd = true; + LOCK.notifyAll(); + } + } + }; + + DragGestureListener dgl = dge -> + dge.startDrag(null, new StringSelection("test"), dsl); + + new DragSource().createDefaultDragGestureRecognizer(panel, + DnDConstants.ACTION_COPY_OR_MOVE, dgl); + + DropTargetListener dtl = new DropTargetAdapter() { + public void drop(DropTargetDropEvent e) { + System.err.println("DropTargetListener.drop(): " + + "accepting the user drop action=" + e.getDropAction()); + e.acceptDrop(e.getDropAction()); + e.dropComplete(true); + } + }; + + new DropTarget(frame, DnDConstants.ACTION_COPY_OR_MOVE, dtl); + + Point startPoint = new Point(Util.blockTillDisplayed(panel)); + startPoint.translate(50, 50); + Point endPoint = new Point(startPoint.x + + DragSource.getDragThreshold() + 10, + startPoint.y + DragSource.getDragThreshold() + 10); + + synchronized (LOCK) { + robot.keyPress(KeyEvent.VK_CONTROL); + Util.doDragDrop(robot, startPoint, endPoint); + robot.keyRelease(KeyEvent.VK_CONTROL); + LOCK.wait(WAIT_TIMEOUT); + } + if (!firstEnd) { + System.err.println("DragSourseListener.dragDropEnd() " + + "was not called, returning"); + return; + } + + synchronized (LOCK) { + Util.doDragDrop(robot, startPoint, endPoint); + LOCK.wait(WAIT_TIMEOUT); + } + if (!secondEnd) { + System.err.println("DragSourseListener.dragDropEnd() " + + "was not called, returning"); + return; + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (failed) { + throw new RuntimeException("wrong next drop action!"); + } + + System.err.println("test passed!"); + } +} + +class Util { + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + public static void doDragDrop(Robot robot, Point startPoint, Point endPoint) { + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(Util.sign(endPoint.x - p.x), + Util.sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(100); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + public static Point blockTillDisplayed(Component comp) { + Point p = null; + while (p == null) { + try { + p = comp.getLocationOnScreen(); + } catch (IllegalStateException e) { + try { + Thread.sleep(1000); + } catch (InterruptedException ie) { + } + } + } + return p; + } +} \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NoFormatsDragEnterTest/NoFormatsDragEnterTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,225 @@ +/* + * 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 4702735 + @summary tests that a dragEnter is called even if the source doesn't + export data in native formats. + @key headful + @run main NoFormatsDragEnterTest +*/ + +import java.awt.AWTException; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +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.DragSourceAdapter; +import java.awt.dnd.DragSourceListener; +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.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + + +public class NoFormatsDragEnterTest { + + Frame frame; + DragSourcePanel dragSourcePanel; + DropTargetPanel dropTargetPanel; + + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int DROP_COMPLETION_TIMEOUT = 1000; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NoFormatsDragEnterTest noFormatsDragEnterTest = new NoFormatsDragEnterTest(); + EventQueue.invokeAndWait(noFormatsDragEnterTest::init); + noFormatsDragEnterTest.start(); + } + + public void init() { + frame = new Frame(); + dragSourcePanel = new DragSourcePanel(); + dropTargetPanel = new DropTargetPanel(); + + frame.setTitle("NoFormatsDragEnterTest"); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourcePanel); + frame.add(dropTargetPanel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void start() throws AWTException, InterruptedException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + final Point srcPoint = dragSourcePanel.getLocationOnScreen(); + Dimension d = dragSourcePanel.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + final Point dstPoint = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + dstPoint.translate(d.width / 2, d.height / 2); + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point curPoint = new Point(srcPoint); + !curPoint.equals(dstPoint); + curPoint.translate(sign(dstPoint.x - curPoint.x), + sign(dstPoint.y - curPoint.y))) { + robot.mouseMove(curPoint.x, curPoint.y); + robot.delay(100); + } + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(DROP_COMPLETION_TIMEOUT); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (!dropTargetPanel.passed()) { + throw new RuntimeException("Drop doesn't happen."); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n > 0 ? 1 : 0; + } +} + +class DragSourcePanel extends Canvas implements DragGestureListener { + + private final Dimension preferredDimension = new Dimension(200, 100); + private final DragSourceListener listener = new DragSourceAdapter() {}; + + public DragSourcePanel() { + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY_OR_MOVE, + this); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, new TestTransferable(), listener); + } +} + +class TestTransferable implements Transferable { + + public static DataFlavor dataFlavor = null; + static final Object data = new Object(); + + static { + DataFlavor df = null; + try { + df = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + + "; class=java.lang.Object"); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e); + } + dataFlavor = df; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor df) { + return dataFlavor.equals(df); + } + + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException, IOException { + if (!isDataFlavorSupported(df)) { + throw new UnsupportedFlavorException(df); + } + return data; + } +} + +class DropTargetPanel extends Canvas implements DropTargetListener { + + private final Dimension preferredDimension = new Dimension(200, 100); + private boolean dragEnterTriggered = false; + private boolean dragOverTriggered = false; + + public DropTargetPanel() { + setDropTarget(new DropTarget(this, this)); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragEnter(DropTargetDragEvent dtde) { + dragEnterTriggered = true; + } + + public void dragExit(DropTargetEvent dte) {} + + public void dragOver(DropTargetDragEvent dtde) { + dragOverTriggered = true; + } + + public void dropActionChanged(DropTargetDragEvent dtde) {} + + public void drop(DropTargetDropEvent dtde) { + dtde.rejectDrop(); + } + + public boolean passed() { + // asserts that dragEnter has been called if dragOver has been called. + return !dragOverTriggered || dragEnterTriggered; + } +} \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NoFormatsDropTest/NoFormatsDropTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,297 @@ +/* + * 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 4473062 + @summary tests that a drop happens even if the source doesn't export + data in native formats. + @key headful + @run main NoFormatsDropTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +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.DragSourceAdapter; +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.IOException; +import java.lang.reflect.InvocationTargetException; + +public class NoFormatsDropTest implements AWTEventListener { + + Frame frame; + DragSourcePanel dragSourcePanel; + DropTargetPanel dropTargetPanel; + + static final int FRAME_ACTIVATION_TIMEOUT = 1000; + static final int DROP_COMPLETION_TIMEOUT = 1000; + static final int MOUSE_RELEASE_TIMEOUT = 1000; + static final Object SYNC_LOCK = new Object(); + + Component clickedComponent = null; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + NoFormatsDropTest noFormatsDropTest = new NoFormatsDropTest(); + EventQueue.invokeAndWait(noFormatsDropTest::init); + noFormatsDropTest.start(); + } + + public void init() { + frame = new Frame(); + dragSourcePanel = new DragSourcePanel(); + dropTargetPanel = new DropTargetPanel(); + + frame.setTitle("NoFormatsDropTest"); + frame.setLayout(new GridLayout(2, 1)); + frame.add(dragSourcePanel); + frame.add(dropTargetPanel); + + frame.getToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void start() throws InterruptedException, AWTException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.delay(FRAME_ACTIVATION_TIMEOUT); + + final Point srcPoint = dragSourcePanel.getLocationOnScreen(); + Dimension d = dragSourcePanel.getSize(); + srcPoint.translate(d.width / 2, d.height / 2); + + if (!pointInComponent(robot, srcPoint, dragSourcePanel)) { + System.err.println("WARNING: Couldn't locate source panel."); + return; + } + + final Point dstPoint = dropTargetPanel.getLocationOnScreen(); + d = dropTargetPanel.getSize(); + dstPoint.translate(d.width / 2, d.height / 2); + + if (!pointInComponent(robot, dstPoint, dropTargetPanel)) { + System.err.println("WARNING: Couldn't locate target panel."); + return; + } + + robot.mouseMove(srcPoint.x, srcPoint.y); + robot.keyPress(KeyEvent.VK_CONTROL); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point curPoint = new Point(srcPoint); + !curPoint.equals(dstPoint); + curPoint.translate(sign(dstPoint.x - curPoint.x), + sign(dstPoint.y - curPoint.y))) { + robot.mouseMove(curPoint.x, curPoint.y); + robot.delay(100); + } + robot.keyRelease(KeyEvent.VK_CONTROL); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.delay(DROP_COMPLETION_TIMEOUT); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (!dropTargetPanel.passed()) { + throw new RuntimeException("Drop doesn't happen."); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n > 0 ? 1 : 0; + } + + public 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(); + } + } + } + + boolean pointInComponent(Robot robot, Point p, Component comp) + throws InterruptedException { + 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; + } +} + +class DragSourcePanel extends Panel implements DragGestureListener { + + private final Dimension preferredDimension = new Dimension(200, 100); + private final DragSourceListener listener = new DragSourceAdapter() {}; + + public DragSourcePanel() { + DragSource ds = DragSource.getDefaultDragSource(); + ds.createDefaultDragGestureRecognizer(this, + DnDConstants.ACTION_COPY_OR_MOVE, + this); + } + + public Dimension getPreferredSize() { + return preferredDimension; + } + + public void dragGestureRecognized(DragGestureEvent dge) { + dge.startDrag(null, new TestTransferable(), listener); + } +} + +class TestTransferable implements Transferable { + + public static DataFlavor dataFlavor = null; + static final Object data = new Object(); + + static { + DataFlavor df = null; + try { + df = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + + "; class=java.lang.Object"); + } catch (ClassNotFoundException e) { + throw new ExceptionInInitializerError(e); + } + dataFlavor = df; + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] { dataFlavor }; + } + + public boolean isDataFlavorSupported(DataFlavor df) { + return dataFlavor.equals(df); + } + + public Object getTransferData(DataFlavor df) + throws UnsupportedFlavorException, IOException { + if (!isDataFlavorSupported(df)) { + throw new UnsupportedFlavorException(df); + } + return data; + } +} + +class DropTargetPanel extends Panel implements DropTargetListener { + + final Dimension preferredDimension = new Dimension(200, 100); + boolean passed = false; + + 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(); + } + + Transferable transfer = dtde.getTransferable(); + + if (transfer.isDataFlavorSupported(TestTransferable.dataFlavor)) { + try { + Object data = + transfer.getTransferData(TestTransferable.dataFlavor); + passed = true; + dtc.dropComplete(true); + } catch (IOException e) { + e.printStackTrace(); + dtc.dropComplete(false); + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + dtc.dropComplete(false); + } + } else { + dtc.dropComplete(false); + } + } + + boolean passed() { + return passed; + } +} \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NoTargetNoDragExitTest/NoTargetNoDragExitTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,217 @@ +/* + * 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 4874092 + @summary tests that DragSourceListener.dragExit() is not called if the mouse + is not dragged over any drop site + @key headful + @run main NoTargetNoDragExitTest +*/ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; +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.DragSourceDropEvent; +import java.awt.dnd.DragSourceEvent; +import java.awt.dnd.DragSourceListener; +import java.awt.event.AWTEventListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; + + +public class NoTargetNoDragExitTest { + private volatile boolean failed; + private volatile boolean end; + private final Object LOCK = new Object(); + private Frame frame; + private Panel panel; + + public static void main(String[] args) throws Exception { + NoTargetNoDragExitTest noTargetNoDragExitTest = new NoTargetNoDragExitTest(); + EventQueue.invokeAndWait(noTargetNoDragExitTest::init); + noTargetNoDragExitTest.start(); + } + + public void init() { + frame = new Frame("NoTargetNoDragExitTest"); + panel = new Panel(); + frame.add(panel); + frame.setSize(300, 300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.validate(); + } + + public void start() throws Exception { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + final DragSourceListener dsl = new DragSourceAdapter() { + public void dragExit(DragSourceEvent e) { + failed = true; + System.err.println("FAILURE: DragSourceListener.dragExit() called!"); + } + public void dragDropEnd(DragSourceDropEvent e) { + System.err.println("DragSourceListener.dragDropEnd()"); + synchronized (LOCK) { + end = true; + LOCK.notifyAll(); + } + } + }; + + DragGestureListener dgl = dge -> + dge.startDrag(null, new StringSelection("NoTargetNoDragExitTest"), dsl); + + new DragSource().createDefaultDragGestureRecognizer(panel, + DnDConstants.ACTION_COPY_OR_MOVE, dgl); + + Point startPoint = frame.getLocationOnScreen(); + startPoint.translate(50, 50); + Point endPoint = new Point(startPoint.x + 100, startPoint.y + 100); + + Util.waitForInit(); + + if (!Util.pointInComponent(robot, startPoint, frame)) { + System.err.println("WARNING: Could not locate " + frame + + " at point " + startPoint); + return; + } + + robot.mouseMove(startPoint.x, startPoint.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + for (Point p = new Point(startPoint); !p.equals(endPoint); + p.translate(Util.sign(endPoint.x - p.x), + Util.sign(endPoint.y - p.y))) { + robot.mouseMove(p.x, p.y); + robot.delay(100); + } + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + synchronized (LOCK) { + while (!end) { + LOCK.wait(); + } + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } + } + + if (failed) { + throw new RuntimeException("DragSourceListener.dragExit() called!"); + } + + System.err.println("test passed!"); + } +} + + +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(); + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } +} \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/dnd/NotReallySerializableTest/NotReallySerializableTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * 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 + @key headful + @bug 4187912 + @summary Test that some incorrectly written DnD code cannot hang the app + @run main NotReallySerializableTest +*/ + +import java.awt.Button; +import java.awt.Cursor; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.datatransfer.StringSelection; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragGestureRecognizer; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; +import java.awt.dnd.DragSourceContext; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetAdapter; +import java.awt.dnd.DropTargetDropEvent; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.util.ArrayList; + + +public class NotReallySerializableTest { + public static void main(String[] args) throws IOException { + Toolkit tk = Toolkit.getDefaultToolkit(); + + DragGestureRecognizer dgr = tk.createDragGestureRecognizer + (java.awt.dnd.MouseDragGestureRecognizer.class, + DragSource.getDefaultDragSource(), new Button(), + DnDConstants.ACTION_LINK, new TrickDragGestureListener()); + DragGestureEvent dge = new DragGestureEvent + (dgr, DnDConstants.ACTION_LINK, new Point(0, 0), + new TrickList()); + DragSourceContext dsc = new DragSourceContext(dge, + Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR), + null, null, new TrickTransferable(), + new TrickDragSourceListener()); + DropTarget dt = new DropTarget(new Button(), + new TrickDropTargetListener()); + + ObjectOutputStream stream = new ObjectOutputStream + (new OutputStream() { + public void write(int b) {} + }); + + stream.writeObject(dgr); + stream.writeObject(dge); + stream.writeObject(dsc); + stream.writeObject(dt); + + System.out.println("test passed"); + } +} + +class TrickList extends ArrayList implements Serializable { + Object trick = new Object(); + + TrickList() { + add(trick); + } +} + +class TrickDragGestureListener implements DragGestureListener, Serializable { + Object trick = new Object(); + + public void dragGestureRecognized(DragGestureEvent dge) {} +} + +class TrickTransferable extends StringSelection implements Serializable { + Object trick = new Object(); + + TrickTransferable() { + super(""); + } +} + +class TrickDragSourceListener extends DragSourceAdapter + implements Serializable +{ + Object trick = new Object(); +} + +class TrickDropTargetListener extends DropTargetAdapter + implements Serializable +{ + Object trick = new Object(); + + public void drop(DropTargetDropEvent dtde) {} +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/EventDispatchThread/StoppingEdtOnPushPopTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * 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 4848555 + @summary Popping an event queue could cause its thread to restart inadvertently + @run main StoppingEdtOnPushPopTest +*/ + +import java.awt.AWTEvent; +import java.awt.ActiveEvent; +import java.awt.EventQueue; +import java.awt.Toolkit; + +public class StoppingEdtOnPushPopTest implements Runnable { + public void start() { + int before = countEventQueues(); + try { + for (int i = 0; i < 10; i++) { + EventQueue.invokeAndWait(this); + } + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } catch (java.lang.reflect.InvocationTargetException e) { + e.printStackTrace(); + throw new RuntimeException("InvocationTargetException occurred"); + } + pause(1000); + int after = countEventQueues(); + if (before < after && after > 1) { + throw new RuntimeException("Test failed (before=" + before + + "; after=" + after + ")"); + } + System.out.println("Test passed"); + } + + public void run() { + System.out.println("push/pop"); + MyEventQueue queue = new MyEventQueue(); + Toolkit.getDefaultToolkit().getSystemEventQueue().push(queue); + Toolkit.getDefaultToolkit().getSystemEventQueue() + .postEvent(new EmptyEvent()); + queue.pop(); + } + + public int countEventQueues() { + int count = 0; + System.out.println("All threads currently running in the system"); + Thread threads[] = new Thread[Thread.activeCount()]; + Thread.enumerate(threads); + for (int i = 0; i < threads.length; ++i) { + Thread thread = threads[i]; + if (thread != null) { + System.out.println(thread.getName()); + if (thread.getName().startsWith("AWT-EventQueue")) { + count++; + } + } + } + return count; + } + + public void pause(long aMillis) { + try { + Thread.sleep(aMillis); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } + } + + public static void main(String[] args) { + StoppingEdtOnPushPopTest test = new StoppingEdtOnPushPopTest(); + test.start(); + } +} + +class MyEventQueue extends EventQueue { + public MyEventQueue() { + super(); + } + + public void pop() { + super.pop(); + } +} + +class EmptyEvent extends AWTEvent implements ActiveEvent { + public EmptyEvent() { + super(new Object(), 0); + } + + public void dispatch() { + System.out.println("one more EmptyEvent"); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java openjdk-lts-11.0.21+9/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/FileDialog/ExceptionAfterSetDirectory.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6308332 + @summary FileDialog.setDirectory() throws exception on Linux & Solaris + @key headful + @run main ExceptionAfterSetDirectory +*/ + +import java.awt.AWTException; +import java.awt.EventQueue; +import java.awt.FileDialog; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +public class ExceptionAfterSetDirectory { + FileDialog fd = null; + Frame frame; + + public void start() throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ExceptionAfterSetDirectory"); + frame.setLayout(new FlowLayout()); + frame.setBounds(100, 100, 100, 100); + frame.setVisible(true); + fd = new FileDialog(frame, "file dialog", FileDialog.LOAD); + }); + + try { + test(); + } catch (Exception e) { + throw new RuntimeException("Test failed.", e); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + if (fd != null) { + EventQueue.invokeAndWait(fd::dispose);; + } + } + } + + private void test() throws InterruptedException, InvocationTargetException { + final Robot r; + + try { + r = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Can not initialize Robot.", e); + } + + r.setAutoDelay(200); + r.delay(500); + + EventQueue.invokeLater(() -> { + fd.setVisible(true); + }); + r.delay(2000); + r.waitForIdle(); + + if (System.getProperty("os.name").contains("OS X")) { + // Workaround for JDK-7186009 - try to close file dialog pressing escape + r.keyPress(KeyEvent.VK_ESCAPE); + r.keyRelease(KeyEvent.VK_ESCAPE); + r.delay(2000); + r.waitForIdle(); + } + + if (fd.isVisible()) { + EventQueue.invokeAndWait(() -> { + fd.setVisible(false); + }); + r.delay(2000); + r.waitForIdle(); + } + + // Changing directory on hidden file dialog should not cause an exception + EventQueue.invokeAndWait(() -> { + fd.setDirectory("/"); + }); + r.delay(2000); + r.waitForIdle(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ExceptionAfterSetDirectory test = new ExceptionAfterSetDirectory(); + test.start(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java openjdk-lts-11.0.21+9/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/FlowLayout/MinimumLayoutSize.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,98 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6257219 + @summary FlowLayout gives a wrong minimum size if the first component is hidden. + @key headful + @run main MinimumLayoutSize +*/ + + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.LayoutManager; +import java.awt.Panel; +import java.awt.Robot; +import java.lang.reflect.InvocationTargetException; + +public class MinimumLayoutSize { + Frame frame; + Button b1; + Button b2; + Panel panel; + + public void start() throws AWTException, + InterruptedException, InvocationTargetException { + try { + Robot robot = new Robot(); + LayoutManager layout = new FlowLayout(FlowLayout.LEFT, 100, 0); + final int[] widths = new int[2]; + EventQueue.invokeAndWait(() -> { + frame = new Frame("MinimumLayoutSize"); + b1 = new Button("B1"); + b2 = new Button("B2"); + panel = new Panel(); + panel.add(b2); + frame.add(panel); + frame.pack(); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + //add hidden component b1 + EventQueue.invokeAndWait(() -> { + widths[0] = layout.minimumLayoutSize(panel).width; + b1.setVisible(false); + panel.add(b1, 0); + }); + robot.waitForIdle(); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + widths[1] = layout.minimumLayoutSize(panel).width; + frame.setVisible(false); + }); + System.out.println("TRACE: w1 = " + widths[0] + " w2 = " + widths[1]); + + if (widths[0] != widths[1]) { + throw new RuntimeException("Test FAILED. Minimum sizes are not equal." + + " w1 = " + widths[0] + " w2 = " + widths[1]); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + System.out.println("Test passed"); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException, AWTException { + MinimumLayoutSize test = new MinimumLayoutSize(); + test.start(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java openjdk-lts-11.0.21+9/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/FlowLayout/PreferredLayoutSize.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * 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 4284124 + @summary FlowLayout gives a wrong size if the first component is hidden. + @key headful + @run main PreferredLayoutSize +*/ + +import java.awt.Button; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.lang.reflect.InvocationTargetException; + +public class PreferredLayoutSize { + public void start() { + Frame f = new Frame("PreferredLayoutSize"); + int[] widths = new int[2]; + + try { + f.setLocationRelativeTo(null); + Button b1 = new Button("button 1"); + Button b2 = new Button("button 2"); + f.setLayout(new FlowLayout(FlowLayout.LEFT, 50, 5)); + f.add(b1); + f.add(b2); + f.pack(); + f.setVisible(true); + b1.setVisible(false); + b2.setVisible(true); + Dimension d1 = f.getPreferredSize(); + Dimension d2 = b2.getPreferredSize(); + widths[0] = d1.width - d2.width; + b1.setVisible(true); + b2.setVisible(false); + d1 = f.getPreferredSize(); + d2 = b1.getPreferredSize(); + widths[1] = d1.width - d2.width; + f.setVisible(false); + } finally { + f.dispose(); + } + + if (widths[0] != widths[1]) { + throw new RuntimeException("Test FAILED"); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + PreferredLayoutSize test = new PreferredLayoutSize(); + EventQueue.invokeAndWait(test::start); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/AsyncUpFocusCycleTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,186 @@ +/* + * 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 4394789 + @summary KeyboardFocusManager.upFocusCycle is not working for Swing properly + @key headful + @run main AsyncUpFocusCycleTest +*/ + + +import javax.swing.DefaultFocusManager; +import javax.swing.JButton; +import javax.swing.JFrame; +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; + +public class AsyncUpFocusCycleTest { + volatile boolean isFailed = true; + Object sema = new Object(); + JFrame frame; + Point location; + JButton button; + Insets insets; + int width; + + public void start() throws InterruptedException, + InvocationTargetException { + try { + Robot robot = new Robot(); + robot.mouseMove(100, 100); + + EventQueue.invokeAndWait(() -> { + frame = new JFrame("AsyncUpFocusCycleTest") { + public void requestFocus() { + boolean ret = super.requestFocus(false); + System.err.println("requestFocus() on Frame " + ret); + } + + protected boolean requestFocus(boolean temporary) { + boolean ret = super.requestFocus(temporary); + System.err.println("requestFocus(" + temporary + ") on Frame " + ret); + return ret; + } + + public boolean requestFocusInWindow() { + boolean ret = super.requestFocusInWindow(); + System.err.println("requestFocusInWindow() on Frame " + ret); + return ret; + } + + protected boolean requestFocusInWindow(boolean temporary) { + boolean ret = super.requestFocusInWindow(temporary); + System.err.println("requestFocusInWindow(" + temporary + ") on Frame " + ret); + return ret; + } + }; + + Container container1 = frame.getContentPane(); + container1.setBackground(Color.yellow); + + button = new JButton("Button") { + public void requestFocus() { + boolean ret = super.requestFocus(false); + System.err.println("requestFocus() on Button " + ret); + } + + public boolean requestFocus(boolean temporary) { + boolean ret = super.requestFocus(temporary); + System.err.println("requestFocus(" + temporary + ") on Button " + ret); + return ret; + } + + public boolean requestFocusInWindow() { + boolean ret = super.requestFocusInWindow(); + System.err.println("requestFocusInWindow() on Button " + ret); + return ret; + } + + protected boolean requestFocusInWindow(boolean temporary) { + boolean ret = super.requestFocusInWindow(temporary); + System.err.println("requestFocusInWindow(" + temporary + ") on Button " + ret); + return ret; + } + }; + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Button receive focus"); + frame.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Frame receive focus"); + synchronized (sema) { + isFailed = false; + sema.notifyAll(); + } + } + }); + } + }); + container1.add(new JButton("empty button"), BorderLayout.WEST); + container1.add(button, BorderLayout.EAST); + frame.setBounds(0, 0, 300, 300); + frame.setVisible(true); + }); + + robot.delay(2000); + robot.waitForIdle(); + + EventQueue.invokeAndWait(() -> { + location = frame.getLocationOnScreen(); + insets = frame.getInsets(); + width = frame.getWidth(); + }); + + robot.mouseMove(location.x + width / 2, location.y + insets.top / 2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + DefaultKeyboardFocusManager manager = new DefaultFocusManager(); + robot.delay(1000); + EventQueue.invokeAndWait(button::requestFocus); + robot.delay(1000); + EventQueue.invokeAndWait(() -> { + manager.upFocusCycle(button); + }); + + try { + synchronized (sema) { + sema.wait(5000); + } + + if (isFailed) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED"); + } else { + System.out.println("Test PASSED"); + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted"); + } + } catch (AWTException e) { + System.out.println("Problem creating Robot."); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + AsyncUpFocusCycleTest test = new AsyncUpFocusCycleTest(); + test.start(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ClearMostRecentFocusOwnerTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,307 @@ +/* + * 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 4525962 + @summary Opposite component calculated inaccurately + @key headful + @run main ClearMostRecentFocusOwnerTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +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.Insets; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; + +import java.awt.event.AWTEventListener; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ClearMostRecentFocusOwnerTest implements AWTEventListener { + final static int ROBOT_DELAY = 50; + volatile Frame firstFrame; + volatile Frame secondFrame; + volatile Button actionButton; + volatile Button btnToRemove; + volatile Button btnToHide; + volatile Button btnToDisable; + volatile Button btnToNonFocusable; + volatile Panel pnlToHide; + volatile Button btnInPanel; + + Robot robot; + + volatile Component opposite = null; + volatile Component focusOwner = null; + volatile Object monitor = null; + + public void init() throws InterruptedException, + InvocationTargetException { + try { + robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Can not create awt-robot."); + } + EventQueue.invokeAndWait(() -> { + firstFrame = new Frame("The First Frame"); + firstFrame.setName("\"1st Frame\""); + secondFrame = new Frame("The Second Frame"); + secondFrame.setName("\"2nd Frame\""); + pnlToHide = new Panel(); + pnlToHide.setName("Panel"); + actionButton = new Button("Action Button"); + actionButton.setName("\"" + actionButton.getLabel() + "\""); + btnToRemove = new Button("To Remove"); + btnToRemove.setName("\"" + btnToRemove.getLabel() + "\""); + btnToHide = new Button("ToHide"); + btnToHide.setName("\"" + btnToHide.getLabel() + "\""); + btnToDisable = new Button("To Disable"); + btnToDisable.setName("\"" + btnToDisable.getLabel() + "\""); + btnToNonFocusable = new Button("To setFocusable(false)"); + btnToNonFocusable.setName("\"" + btnToNonFocusable.getLabel() + "\""); + btnInPanel = new Button("Int Panel"); + btnInPanel.setName("\"" + btnInPanel.getLabel() + "\""); + + firstFrame.add(actionButton); + + secondFrame.setLayout(new FlowLayout()); + secondFrame.add(btnToRemove); + secondFrame.add(btnToHide); + secondFrame.add(btnToDisable); + secondFrame.add(btnToNonFocusable); + secondFrame.add(pnlToHide); + pnlToHide.add(btnInPanel); + + firstFrame.pack(); + firstFrame.setVisible(true); + secondFrame.pack(); + secondFrame.setLocation(0, firstFrame.getHeight() + 50); + secondFrame.setVisible(true); + }); + } + + public void start() throws InterruptedException, InvocationTargetException { + try { + Toolkit.getDefaultToolkit(). + addAWTEventListener(this, + AWTEvent.FOCUS_EVENT_MASK); + + makeFocusOwner(btnToRemove); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + secondFrame.remove(btnToRemove); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnToHide) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.remove()."); + } + + makeFocusOwner(btnToHide); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + btnToHide.setVisible(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnToDisable) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.setVisible(false)."); + } + + makeFocusOwner(btnToDisable); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + btnToDisable.setEnabled(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnToNonFocusable) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.rsetEnabled(false)."); + } + + makeFocusOwner(btnToNonFocusable); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + btnToNonFocusable.setFocusable(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite != btnInPanel) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Component.setFocusable(false)."); + } + + makeFocusOwner(btnInPanel); + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(false); + pnlToHide.setVisible(false); + }); + makeFocusOwner(actionButton); + opposite = null; + EventQueue.invokeAndWait(() -> { + secondFrame.setVisible(true); + }); + makeActiveFrame(secondFrame); + if (opposite == btnInPanel) { + System.out.println("opposite = " + opposite); + throw new RuntimeException("Test FAILED: wrong opposite after Container.setVisible(false)."); + } + } finally { + if (firstFrame != null) { + EventQueue.invokeAndWait(firstFrame::dispose); + } + if (secondFrame != null) { + EventQueue.invokeAndWait(secondFrame::dispose); + } + + } + } + + public void eventDispatched(AWTEvent event) { + switch (event.getID()) { + case FocusEvent.FOCUS_GAINED: + if (focusOwner == ((FocusEvent) event).getComponent() + && monitor != null) { + synchronized (monitor) { + monitor.notify(); + } + } + break; + case FocusEvent.FOCUS_LOST: + opposite = ((FocusEvent) event).getOppositeComponent(); + break; + } + System.out.println(event); + } + + void clickOnComponent(Component comp) throws InterruptedException, + InvocationTargetException { + System.err.println("clickOnComopnent " + comp.getName()); + robot.delay(3000); + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point origin = comp.getLocationOnScreen(); + Dimension dim = comp.getSize(); + point[0] = origin.x + (int) dim.getWidth() / 2; + point[1] = origin.y + (int) dim.getHeight() / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(ROBOT_DELAY); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + void makeFocusOwner(Component comp) throws InterruptedException, + InvocationTargetException { + AtomicBoolean isOwner = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isOwner.set(comp.isFocusOwner()); + }); + if (!isOwner.get()) { + clickOnComponent(comp); + try { + EventQueue.invokeAndWait(() -> { + isOwner.set(comp.isFocusOwner()); + }); + if (!isOwner.get()) { + monitor = new Object(); + focusOwner = comp; + synchronized (monitor) { + monitor.wait(3000); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException("Test was interrupted."); + } + } + EventQueue.invokeAndWait(() -> { + isOwner.set(comp.isFocusOwner()); + }); + if (!isOwner.get()) { + throw new RuntimeException("Test can not make " + + comp.getName() + " a focus owner."); + } + } + + void makeActiveFrame(Frame frame) throws InvocationTargetException, + InterruptedException { + robot.delay(3000); + if (!frame.isActive()) { + System.err.println("frame is not active"); + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point origin = frame.getLocationOnScreen(); + Insets ins = frame.getInsets(); + point[0] = origin.x + frame.getWidth() / 2; + point[1] = origin.y + ins.top / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(ROBOT_DELAY); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + robot.delay(3000); + EventQueue.invokeAndWait(() -> { + if (!frame.isActive()) { + throw new RuntimeException("Test can not activate " + frame.getName() + "."); + } + }); + } + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + ClearMostRecentFocusOwnerTest test = new ClearMostRecentFocusOwnerTest(); + test.init(); + test.start(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ConsumedTabKeyTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,232 @@ +/* + * 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 4715649 +@summary Tests that KEY_TYPED event for Tab key arrives if Tab key is not focus traversal key +@key headful +@run main ConsumedTabKeyTest +*/ + +import java.awt.AWTEvent; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; + +public class ConsumedTabKeyTest extends Panel { + TextField text; + Button button = new Button("none"); + Semaphore focusSema = new Semaphore(); + Semaphore releaseSema = new Semaphore(); + Semaphore buttonFocusSema = new Semaphore(); + Robot robot; + volatile boolean keyTyped; + volatile boolean hasFocus; + static Frame frame; + + public void init() { + this.setLayout(new FlowLayout()); + text = new TextField(); + + text.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + focusSema.raise(); + } + }); + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + buttonFocusSema.raise(); + } + }); + add(text); + add(button); + setSize(200, 200); + setVisible(true); + validate(); + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + if (e.getID() == KeyEvent.KEY_RELEASED) { + releaseSema.raise(); + } + if (e.getID() == KeyEvent.KEY_TYPED) { + keyTyped = true; + } + } + }, InputEvent.KEY_EVENT_MASK); + try { + robot = new Robot(); + } catch (Exception re) { + throw new RuntimeException("Couldn't create Robot"); + } + } + + public void start() throws InterruptedException, + InvocationTargetException { + EventQueue.invokeAndWait(() -> { + if (!text.isFocusOwner()) { + text.requestFocus(); + } + + text.setFocusTraversalKeysEnabled(false); + }); + + try { + focusSema.doWait(1000); + } catch (InterruptedException ie1) { + throw new RuntimeException("Interrupted"); + } + + EventQueue.invokeAndWait(() -> { + hasFocus = text.isFocusOwner(); + }); + + if (!focusSema.getState() && !hasFocus) { + throw new RuntimeException("Text didn't receive focus"); + } + + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + try { + releaseSema.doWait(1000); + } catch (InterruptedException ie2) { + throw new RuntimeException("Interrupted"); + } + + if (!releaseSema.getState()) { + throw new RuntimeException("KEY_RELEASED hasn't arrived"); + } + + if (!keyTyped) { + throw new RuntimeException("KEY_TYPED for Tab key hasn't arrived"); + } + + EventQueue.invokeAndWait(() -> { + text.setFocusTraversalKeysEnabled(true); + }); + + releaseSema.setState(false); + robot.keyPress(KeyEvent.VK_TAB); + robot.keyRelease(KeyEvent.VK_TAB); + try { + buttonFocusSema.doWait(1000); + releaseSema.doWait(1000); + } catch (InterruptedException ie2) { + throw new RuntimeException("Interrupted"); + } + + EventQueue.invokeAndWait(() -> { + hasFocus = button.isFocusOwner(); + }); + + if (!buttonFocusSema.getState() && !hasFocus) { + throw new RuntimeException("Button hasn't received focus"); + } + keyTyped = false; + releaseSema.setState(false); + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + try { + releaseSema.doWait(1000); + } catch (InterruptedException ie2) { + throw new RuntimeException("Interrupted"); + } + + if (!releaseSema.getState()) { + throw new RuntimeException("KEY_RELEASED hasn't arrived"); + } + if (!keyTyped) { + throw new RuntimeException("KEY_TYPED for A key hasn't arrived"); + } + System.err.println("PASSED"); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ConsumedTabKeyTest test = new ConsumedTabKeyTest(); + + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("InvocationTargetException"); + frame.setLayout(new BorderLayout()); + frame.add(test, BorderLayout.CENTER); + test.init(); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + test.start(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } +} + +class Semaphore { + boolean state = false; + int waiting = 0; + + 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 -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/EventRetargetTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/EventRetargetTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/EventRetargetTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/EventRetargetTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * 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 4846162 4626092 + @summary (Key|Window|Focus)Events should not be retargeted when dispatchEvent() is called directly. + @run main EventRetargetTest +*/ + +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +public class EventRetargetTest { + boolean isKEProcessed1; + boolean isKEProcessed2; + boolean isKEProcessed3; + boolean isFEProcessed1; + boolean isFEProcessed2; + boolean isFEProcessed3; + + public void start () { + final Component comp = new Component() { + public boolean isShowing() { + return true; + } + + public boolean isVisible() { + return true; + } + + public boolean isDisplayable() { + return true; + } + + protected void processKeyEvent(KeyEvent e) { + System.err.println("processKeyEvent >> " + e); + isKEProcessed1 = true; + super.processKeyEvent(e); + } + + protected void processFocusEvent(FocusEvent e) { + System.err.println("processFocusEvent >> " + e); + isFEProcessed1 = true; + super.processFocusEvent(e); + } + }; + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + if (e instanceof KeyEvent) { + isKEProcessed2 = (e.getSource() == comp); + } + else if (e instanceof FocusEvent) { + isFEProcessed2 = (e.getSource() == comp); + } + System.err.println("Toolkit >> " + e); + } + }, AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK); + + comp.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + isKEProcessed3 = true; + System.err.println("Listener >> " + e); + } + }); + comp.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + isFEProcessed3 = true; + System.err.println("Listener >> " + e); + } + }); + + KeyEvent ke = new KeyEvent(comp, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, + KeyEvent.VK_UNDEFINED, 'a'); + comp.dispatchEvent(ke); + + if (!(isKEProcessed1 && isKEProcessed2 && isKEProcessed3)) { + System.err.println("(" + isKEProcessed1 + "," + isKEProcessed2 + + "," + isKEProcessed3 + ")"); + throw new RuntimeException("KeyEvent is not correctly retargeted."); + } + + FocusEvent fe = new FocusEvent(comp, FocusEvent.FOCUS_GAINED, + false, null); + comp.dispatchEvent(fe); + + if (!(isFEProcessed1 && isFEProcessed2 && isFEProcessed3)) { + System.err.println("(" + isFEProcessed1 + "," + + isFEProcessed2 + "," + isFEProcessed3 + ")"); + throw new RuntimeException("FocusEvent is not correctly retargeted."); + } + } + + public static void main(String[] args) { + EventRetargetTest test = new EventRetargetTest(); + test.start(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ExtraPropChangeNotifVetoingTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * 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. + */ + +/* + @test + @bug 5072554 + @summary Tests that vetoing focus doesn't generate extra PropertyChange notification. + @key headful + @run main ExtraPropChangeNotifVetoingTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.KeyboardFocusManager; +import java.awt.Panel; +import java.awt.Robot; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; +import java.lang.reflect.InvocationTargetException; + +public class ExtraPropChangeNotifVetoingTest extends Panel { + Button one = new Button("One"); + Button two = new Button("Two"); + Robot robot; + static Frame frame; + + int i = 0; + + public void init() { + try { + robot = new Robot(); + } catch (AWTException e) { + throw new RuntimeException("Error: unable to create robot", e); + } + + setLayout(new FlowLayout()); + add(one); + add(two); + + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener("permanentFocusOwner", + new VetoableChangeListener() { + public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException { + System.out.println((i++) + ". Old=" + e.getOldValue() + ", New=" + e.getNewValue()); + + if (e.getOldValue() == e.getNewValue()) { + throw new RuntimeException("Test failed!"); + } + + if (e.getNewValue() == two) { + System.out.println("VETOING"); + throw new PropertyVetoException("vetoed", e); + } + } + }); + setVisible(true); + } + + public void start() throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(one::requestFocusInWindow); + robot.waitForIdle(); + robot.delay(200); + EventQueue.invokeAndWait(two::requestFocusInWindow); + robot.waitForIdle(); + robot.delay(200); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ExtraPropChangeNotifVetoingTest test = new ExtraPropChangeNotifVetoingTest(); + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ExtraPropChangeNotifVetoingTest"); + frame.setLayout(new BorderLayout()); + frame.add(test, BorderLayout.CENTER); + test.init(); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + test.start(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/FocusForRemovedComponentTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/FocusForRemovedComponentTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/FocusForRemovedComponentTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/FocusForRemovedComponentTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,154 @@ +/* + * 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. + */ + +/* + @test + @bug 4722671 + @summary Accessibility problem in JRE Finder + @key headful + @run main FocusForRemovedComponentTest +*/ + +import java.awt.AWTException; +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.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class FocusForRemovedComponentTest + implements ActionListener { + static int ACTIVATION_TIMEOUT = 2000; + static long WAIT_TIMEOUT = 3000; + volatile Frame frame; + volatile Button btnFirst; + volatile Button btnSecond; + volatile Button btnThird; + + public void start() throws InterruptedException, InvocationTargetException { + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("FocusForRemovedComponentTest"); + btnFirst = new Button("First Button"); + btnSecond = new Button("Second Button"); + btnThird = new Button("Third Button"); + frame.add(btnFirst, BorderLayout.NORTH); + frame.add(btnSecond, BorderLayout.CENTER); + btnFirst.addActionListener(this); + btnFirst.requestFocusInWindow(); + frame.pack(); + frame.setVisible(true); + }); + + try { + Robot robot = new Robot(); + robot.delay(ACTIVATION_TIMEOUT); + int[] location = new int[2]; + EventQueue.invokeAndWait(() -> { + Point button_location = btnFirst.getLocationOnScreen(); + Dimension button_size = btnFirst.getSize(); + location[0] = button_location.x + button_size.width / 2; + location[1] = button_location.y + button_size.height / 2; + }); + robot.mouseMove(location[0], location[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + Object monitor = new Object(); + final MonitoredFocusListener monitorer = new MonitoredFocusListener(monitor); + AtomicBoolean isFocused = new AtomicBoolean(false); + synchronized (monitor) { + EventQueue.invokeAndWait(() -> { + btnThird.addFocusListener(monitorer); + isFocused.set(btnThird.isFocusOwner()); + }); + + if (!isFocused.get()) { + monitor.wait(WAIT_TIMEOUT); + EventQueue.invokeAndWait(() -> { + isFocused.set(btnThird.isFocusOwner()); + }); + } + } + + if (!isFocused.get()) { + throw new RuntimeException("TEST FAILED. The third button is not focus owner."); + } else { + System.out.println("TEST PASSED."); + } + } catch (AWTException e) { + e.printStackTrace(); + throw new RuntimeException("Some AWTException occurred."); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted."); + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + public void actionPerformed(ActionEvent e) { + if (btnSecond.isVisible()) { + btnFirst.setEnabled(false); + frame.remove(btnSecond); + frame.add(btnThird, BorderLayout.CENTER); + btnThird.requestFocusInWindow(); + btnFirst.setEnabled(true); + frame.validate(); + frame.repaint(); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + FocusForRemovedComponentTest test = new FocusForRemovedComponentTest(); + test.start(); + } +} + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusGained(FocusEvent fe) { + synchronized (monitor) { + monitor.notify(); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/FocusTraversalPolicyIAE.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/FocusTraversalPolicyIAE.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/FocusTraversalPolicyIAE.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/FocusTraversalPolicyIAE.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6225100 + @summary FocusTraversalPolicy.getInitialComponent does not work as expected + @run main FocusTraversalPolicyIAE +*/ + +import java.awt.Component; +import java.awt.Container; +import java.awt.FocusTraversalPolicy; + +public class FocusTraversalPolicyIAE { + public static void main(String[] args) { + CustomFocusTraversalPolicy cftp = new CustomFocusTraversalPolicy(); + try { + cftp.getInitialComponent(null); + throw new RuntimeException("Test failed. No exceptions thrown."); + } catch (IllegalArgumentException iae) { + System.out.println("Test passed."); + } catch (NullPointerException npe) { + throw new RuntimeException("Test failed. Unexpected NPE thrown: " + npe); + } catch (Exception e) { + throw new RuntimeException("Test failed. Unexpected exception thrown: " + e); + } + } +} + +class CustomFocusTraversalPolicy extends FocusTraversalPolicy { + public Component getComponentAfter(Container focusCycleRoot, + Component aComponent) { + return null; + } + + public Component getComponentBefore(Container focusCycleRoot, + Component aComponent) { + return null; + } + + public Component getDefaultComponent(Container focusCycleRoot) { + return null; + } + + public Component getFirstComponent(Container focusCycleRoot) { + return null; + } + + public Component getLastComponent(Container focusCycleRoot) { + return null; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/InitialFocusTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/InitialFocusTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/InitialFocusTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/InitialFocusTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * 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 4150021 + @summary if user requests focus on some component, it must become a focus owner after activation + @key headful + @run main InitialFocusTest +*/ + +import java.awt.AWTException; +import java.awt.Button; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class InitialFocusTest implements PropertyChangeListener { + //Declare things used in the test, like buttons and labels here + final static String FOCUSED_WINDOW_PROP = "focusedWindow"; + final static int ACTION_TIMEOUT = 2000; + + volatile Frame frame; + volatile Button btn1; + volatile Button btn2; + + public void start() throws InterruptedException, InvocationTargetException { + DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager(). + addPropertyChangeListener(FOCUSED_WINDOW_PROP, this); + try { + EventQueue.invokeAndWait(() -> { + frame = new Frame("InitialFocusTest"); + frame.setLayout(new FlowLayout()); + btn1 = new Button("First Button"); + frame.add(btn1); + btn2 = new Button("Second Button"); + frame.add(btn2); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + try { + Robot robot = new Robot(); + robot.delay(ACTION_TIMEOUT); + if (!activateFrame(frame, robot, ACTION_TIMEOUT)) { + throw new RuntimeException("Frame was not activated."); + } + robot.delay(ACTION_TIMEOUT); + AtomicBoolean isFocused = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isFocused.set(frame.isFocused()); + }); + if (!isFocused.get()) { + throw new RuntimeException("Frame didn't become focused."); + } + EventQueue.invokeAndWait(() -> { + isFocused.set(btn2.isFocusOwner()); + }); + if (!isFocused.get()) { + throw new RuntimeException("Btn2 didn't receive focus."); + } + } catch (AWTException e) { + e.printStackTrace(); + } + System.out.printf("Test passed."); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } + + public void propertyChange(PropertyChangeEvent pce) { + if (FOCUSED_WINDOW_PROP.equals(pce.getPropertyName())) { + if (pce.getNewValue() == frame) { + System.out.println("requesting focus on btn2"); + btn2.requestFocusInWindow(); + } + } + } + + boolean activateFrame(Frame frame, Robot robot, int timeout) + throws InterruptedException, InvocationTargetException { + AtomicBoolean isActive = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isActive.set(frame.isActive()); + }); + if (!isActive.get()) { + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point origin = frame.getLocationOnScreen(); + Dimension dim = frame.getSize(); + Insets insets = frame.getInsets(); + point[0] = origin.x + dim.width / 2; + point[1] = origin.y + insets.top / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + robot.delay(timeout); + EventQueue.invokeAndWait(() -> { + isActive.set(frame.isActive()); + }); + } + return frame.isActive(); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + InitialFocusTest test = new InitialFocusTest(); + test.start(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/LabelScrollBarFocus.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/LabelScrollBarFocus.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/LabelScrollBarFocus.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/LabelScrollBarFocus.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,180 @@ +/* + * 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 4027897 + @summary Test that Label can't be made focused by the mouse, while ScrollBar should become focused. + @key headful + @run main LabelScrollBarFocus +*/ + +import java.awt.BorderLayout; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Scrollbar; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class LabelScrollBarFocus extends Panel { + static final Semaphore sema = new Semaphore(); + Label lab; + Scrollbar scr; + static Frame frame; + + public void init() { + this.setLayout(new FlowLayout()); + FocusAdapter fa = new FocusAdapter() { + public void focusGained(FocusEvent e) { + sema.raise(); + } + }; + + lab = new Label("Label"); + scr = new Scrollbar(Scrollbar.HORIZONTAL); + lab.addFocusListener(fa); + scr.addFocusListener(fa); + add(lab); + add(scr); + setSize(200, 200); + validate(); + setVisible(true); + } + + public void start() throws InterruptedException, + InvocationTargetException { + Robot robot = null; + try { + robot = new Robot(); + } catch (Exception e) { + throw new RuntimeException("Can't create robot instance"); + } + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point labLoc = lab.getLocationOnScreen(); + point[0] = labLoc.x + 5; + point[1] = labLoc.y + 5; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.waitForIdle(); + try { + sema.doWait(2000); + } catch (InterruptedException ie) { + throw new RuntimeException("Interrupted"); + } + + AtomicBoolean isFocusOwner = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isFocusOwner.set(lab.isFocusOwner()); + }); + if (isFocusOwner.get()) { + throw new RuntimeException("Label is focused"); + } + + EventQueue.invokeAndWait(() -> { + Point scrLoc = scr.getLocationOnScreen(); + point[0] = scrLoc.x + 20; + point[1] = scrLoc.y + 5; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(1000); + robot.waitForIdle(); + try { + sema.doWait(2000); + } catch (InterruptedException ie) { + throw new RuntimeException("Interrupted"); + } + + EventQueue.invokeAndWait(() -> { + isFocusOwner.set(scr.isFocusOwner()); + }); + if (!isFocusOwner.get()) { + throw new RuntimeException("Scroll bar is not focused"); + } + System.out.println("Test passed"); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + try { + LabelScrollBarFocus test = new LabelScrollBarFocus(); + EventQueue.invokeAndWait(() -> { + frame = new Frame("LabelScrollBarFocus"); + test.init(); + frame.setLayout(new BorderLayout()); + frame.add(test, BorderLayout.CENTER); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + }); + test.start(); + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + } + } +} + +class Semaphore { + boolean state = false; + Object lock = new Object(); + int waiting = 0; + + public Semaphore() { + } + + public void doWait(int timeout) throws InterruptedException { + synchronized (lock) { + waiting++; + synchronized (this) { + wait(timeout); + } + waiting--; + } + } + + public void raise() { + synchronized (lock) { + state = true; + if (waiting > 0) { + synchronized (this) { + notifyAll(); + } + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ModalDialogInFocusEventTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ModalDialogInFocusEventTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Focus/ModalDialogInFocusEventTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Focus/ModalDialogInFocusEventTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,414 @@ +/* + * 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 4531693 4636269 4681908 4688142 4691646 4721470 + @summary Showing modal dialog during dispatching SequencedEvent + @key headful + @run main AutomaticAppletTest +*/ + +import java.awt.AWTEvent; +import java.awt.AWTException; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; +import java.awt.event.WindowListener; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class ModalDialogInFocusEventTest + implements ActionListener, Runnable, WindowListener, + WindowFocusListener, FocusListener { + static final int CLICK_DELAY = 50; + static final int ACTIVATION_TIMEOUT = 2000; + static final long STAGE_TIMEOUT = 3 * ACTIVATION_TIMEOUT; + static final StageInfo[] stages = { + new StageInfo(WindowEvent.WINDOW_ACTIVATED, "Window Activated", false), + new StageInfo(WindowEvent.WINDOW_GAINED_FOCUS, "Window Gained Focus", false), + new StageInfo(FocusEvent.FOCUS_GAINED, "Focus Gained", false), + new StageInfo(FocusEvent.FOCUS_LOST, "Focus Lost", true), + new StageInfo(WindowEvent.WINDOW_LOST_FOCUS, "Window Lost Focus", true), + new StageInfo(WindowEvent.WINDOW_DEACTIVATED, "Window Deactivated", true) + }; + static final int MAX_STAGE_NUM = stages.length; + static final Object stageMonitor = new Object(); + + Robot robot = null; + Frame frame; + Frame oppositeFrame; + Dialog dialog; + Button closeButton; + int nStage = MAX_STAGE_NUM; + + public void start() throws InterruptedException, InvocationTargetException { + try { + FocusListener focusEventTracker = new FocusListener() { + public void focusGained(FocusEvent e) { + System.out.println(e); + } + + public void focusLost(FocusEvent e) { + System.out.println(e); + } + }; + + WindowAdapter windowEventTracker = new WindowAdapter() { + public void windowActivated(WindowEvent e) { + System.out.println(e); + } + + public void windowDeactivated(WindowEvent e) { + System.out.println(e); + } + + public void windowGainedFocus(WindowEvent e) { + System.out.println(e); + } + + public void windowLostFocus(WindowEvent e) { + System.out.println(e); + } + }; + EventQueue.invokeAndWait(() -> { + frame = new Frame("ModalDialogInFocusEventTest Main Frame"); + oppositeFrame = new Frame("ModalDialogInFocusEventTest Opposite Frame"); + dialog = new Dialog(frame, "ModalDialogInFocusEventTest Modal Dialog", true); + closeButton = new Button("Close Button"); + closeButton.addActionListener(this); + dialog.add(closeButton); + dialog.setBounds(10, 200, 300, 100); + + dialog.addFocusListener(focusEventTracker); + dialog.addWindowListener(windowEventTracker); + dialog.addWindowFocusListener(windowEventTracker); + oppositeFrame.addFocusListener(focusEventTracker); + oppositeFrame.addWindowListener(windowEventTracker); + oppositeFrame.addWindowFocusListener(windowEventTracker); + + frame.setName("ModalDialogInFocusEventTest MainFrame"); + frame.addFocusListener(this); + frame.addWindowListener(this); + frame.addWindowFocusListener(this); + frame.setSize(300, 100); + + oppositeFrame.setName("ModalDialogInFocusEventTest OppositeName"); + oppositeFrame.setBounds(350, 200, 300, 100); + }); + + + try { + robot = new Robot(); + robot.setAutoDelay(CLICK_DELAY); + + for (int i = 0; i < MAX_STAGE_NUM; i++) { + StageInfo stage = stages[i]; + if (stage.shouldActivateOpposite()) { + EventQueue.invokeAndWait(() -> { + oppositeFrame.setVisible(true); + frame.setVisible(true); + }); + robot.delay(ACTIVATION_TIMEOUT); + AtomicBoolean isActive = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isActive.set(frame.isActive()); + }); + if (!isActive.get()) { + clickOnFrameTitle(frame); + robot.delay(ACTIVATION_TIMEOUT); + } + } else { + EventQueue.invokeAndWait(() -> { + frame.setVisible(true); + oppositeFrame.setVisible(true); + }); + robot.delay(ACTIVATION_TIMEOUT); + AtomicBoolean isActive = new AtomicBoolean(false); + EventQueue.invokeAndWait(() -> { + isActive.set(oppositeFrame.isActive()); + }); + if (!isActive.get()) { + clickOnFrameTitle(oppositeFrame); + robot.delay(ACTIVATION_TIMEOUT); + } + } + + nStage = i; + System.out.println("Stage " + i + " started."); + + synchronized (stageMonitor) { + if (stage.shouldActivateOpposite()) { + clickOnFrameTitle(oppositeFrame); + } else { + clickOnFrameTitle(frame); + } + stageMonitor.wait(STAGE_TIMEOUT); + if (!stage.isFinished()) { + throw new RuntimeException(stages[nStage].toString()); + } + } + EventQueue.invokeAndWait(() -> { + oppositeFrame.setVisible(false); + frame.setVisible(false); + }); + robot.delay(ACTIVATION_TIMEOUT); + } + } catch (AWTException e) { + throw new RuntimeException("Some AWT-Robot problem occurred", e); + } catch (InterruptedException ie) { + ie.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } + } finally { + if (frame != null) { + EventQueue.invokeAndWait(frame::dispose); + } + if (oppositeFrame != null) { + EventQueue.invokeAndWait(oppositeFrame::dispose); + } + if (dialog != null) { + EventQueue.invokeAndWait(dialog::dispose); + } + } + System.out.println("Test passed."); + } + + void clickOnFrameTitle(Frame frame) throws InterruptedException, + InvocationTargetException { + System.out.println("click on title of " + frame.getName()); + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point location = frame.getLocationOnScreen(); + Insets insets = frame.getInsets(); + int width = frame.getWidth(); + point[0] = location.x + width / 2; + point[1] = location.y + insets.top / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + EventQueue.invokeAndWait(frame::requestFocusInWindow); + } + + void openAndCloseModalDialog() throws InterruptedException, + InvocationTargetException { + (new Thread(this)).start(); + dialog.setVisible(true); + } + + void performStage(AWTEvent e) throws InterruptedException, + InvocationTargetException { + if (nStage < MAX_STAGE_NUM && + e.getID() == stages[nStage].getEventID() && + !stages[nStage].isStarted()) { + stages[nStage].start(); + openAndCloseModalDialog(); + stages[nStage].finish(); + synchronized (stageMonitor) { + stageMonitor.notifyAll(); + } + } + } + + public void actionPerformed(ActionEvent ae) { + System.out.println(ae); + dialog.setVisible(false); + } + + public void run() { + try { + Thread.sleep(ACTIVATION_TIMEOUT); + int[] point = new int[2]; + EventQueue.invokeAndWait(() -> { + Point location = closeButton.getLocationOnScreen(); + Dimension dim = closeButton.getSize(); + point[0] = location.x + dim.width / 2; + point[1] = location.y + dim.height / 2; + }); + robot.mouseMove(point[0], point[1]); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + System.out.println("click"); + } catch (InterruptedException | InvocationTargetException ie) { + throw new RuntimeException("Test was interrupted", ie); + } + } + + public void windowOpened(WindowEvent e) { + /* Empty. Unneeded for this test */ + } + + public void windowClosing(WindowEvent e) { + /* Empty. Unneeded for this test */ + } + + public void windowClosed(WindowEvent e) { + /* Empty. Unneeded for this test */ + } + + public void windowIconified(WindowEvent e) { + /* Empty. Unneeded for this test */ + } + + public void windowDeiconified(WindowEvent e) { + /* Empty. Unneeded for this test */ + } + + public void windowActivated(WindowEvent e) { + System.out.println(e); + try { + performStage(e); + } catch (InterruptedException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + + public void windowDeactivated(WindowEvent e) { + System.out.println(e); + try { + performStage(e); + } catch (InterruptedException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + + public void windowGainedFocus(WindowEvent e) { + System.out.println(e); + try { + performStage(e); + } catch (InterruptedException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + + public void windowLostFocus(WindowEvent e) { + System.out.println(e); + try { + performStage(e); + } catch (InterruptedException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + + public void focusGained(FocusEvent e) { + System.out.println(e); + try { + performStage(e); + } catch (InterruptedException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + + public void focusLost(FocusEvent e) { + System.out.println(e); + try { + performStage(e); + } catch (InterruptedException | InvocationTargetException ex) { + throw new RuntimeException(ex); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + ModalDialogInFocusEventTest test = new ModalDialogInFocusEventTest(); + test.start(); + } +} + +class StageInfo { + private String name; + private int eventID; + private boolean started = false; + private boolean finished = false; + + /* + * whether we should activate opposite frame during this stage. + * Note: we need to activate "another" frame BEFORE stage + * i.e. if we should activate frame during stage then we + * need to activate oppositeFrame before it and vice versa. + */ + private boolean activateOpposite; + + StageInfo(int eventID, String name, boolean activateOpposite) { + this.eventID = eventID; + this.name = name; + this.activateOpposite = activateOpposite; + } + + public String toString() { + String str = "Stage [\"" + name + "\""; + if (!started) { + str += " not"; + } + str += " started, "; + if (!finished) { + str += " not"; + } + str += " finished"; + if (activateOpposite) { + str += ", activate opposite"; + } + str += "]"; + return str; + } + + int getEventID() { + return eventID; + } + + boolean isStarted() { + return started; + } + + void start() { + started = true; + System.out.println(this.toString()); + } + + boolean isFinished() { + return finished; + } + + void finish() { + finished = true; + System.out.println(this.toString()); + } + + boolean shouldActivateOpposite() { + return activateOpposite; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/font/FontScaling/StretchedFontTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,222 @@ +/* + * 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.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.imageio.ImageIO; + +import static java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment; +import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING; +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB; +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF; +import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON; +import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR; + +/* + * @test + * @bug 8312555 + * @summary Verifies that hieroglyphs are stretched by AffineTransform.scale(2, 1) + * @run main StretchedFontTest + */ +public final class StretchedFontTest { + private static final String TEXT = "\u6F22"; + private static final int FONT_SIZE = 20; + + private static final Color BACKGROUND = Color.WHITE; + private static final Color[] FOREGROUNDS = { + new Color(0xFF000000, true), + new Color(0x7F000000, true) + }; + + private static final AffineTransform STRETCH_TRANSFORM = + AffineTransform.getScaleInstance(2.0, 1.0); + + public static void main(String[] args) { + List errors = + Arrays.stream(getLocalGraphicsEnvironment() + .getAvailableFontFamilyNames(Locale.ENGLISH)) + .map(family -> new Font(family, Font.PLAIN, FONT_SIZE)) + .filter(font -> font.canDisplay(TEXT.codePointAt(0))) + .map(font -> font.deriveFont(STRETCH_TRANSFORM)) + .flatMap(StretchedFontTest::testFont) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + if (!errors.isEmpty()) { + errors.forEach(System.err::println); + throw new Error(errors.size() + " failure(s) found;" + + " the first one: " + errors.get(0)); + } + } + + /** + * Tests the font with a set of text antialiasing hints. + * + * @param font the font to test + * @return a stream of test results + * @see #testFont(Font, Object) + */ + private static Stream testFont(final Font font) { + return Stream.of(VALUE_TEXT_ANTIALIAS_OFF, + VALUE_TEXT_ANTIALIAS_ON, + VALUE_TEXT_ANTIALIAS_LCD_HRGB) + .flatMap(hint -> testFont(font, hint)); + } + + /** + * Tests the font with the specified text antialiasing hint and a set of + * foreground colors. + * + * @param font the font to test + * @param hint the text antialiasing hint to test + * @return a stream of test results + * @see #testFont(Font, Object, Color) + */ + private static Stream testFont(final Font font, final Object hint) { + return Stream.of(FOREGROUNDS) + .map(foreground -> testFont(font, hint, foreground)); + } + + /** + * Tests the font with the specified text antialiasing hint and + * foreground color. In case of failure, it saves the rendered + * image to a file. + * + * @param font the font to test + * @param hint the text antialiasing hint to test + * @param foreground the foreground color to use + * @return {@code null} if the text rendered correctly; otherwise, + * a {@code String} with the font family name, the value of + * the rendering hint and the color in hex + */ + private static String testFont(final Font font, + final Object hint, + final Color foreground) { + final Dimension size = getTextSize(font); + final BufferedImage image = + new BufferedImage(size.width, size.height, TYPE_3BYTE_BGR); + + final Graphics2D g2d = image.createGraphics(); + try { + g2d.setColor(BACKGROUND); + g2d.fillRect(0, 0, size.width, size.height); + + g2d.setRenderingHint(KEY_TEXT_ANTIALIASING, hint); + g2d.setColor(foreground); + g2d.setFont(font); + g2d.drawString(TEXT, 0, g2d.getFontMetrics(font).getAscent()); + } finally { + g2d.dispose(); + } + + if (verifyImage(image)) { + return null; + } + String fontName = font.getFontName(Locale.ENGLISH); + String hintValue = getHintString(hint); + String hexColor = String.format("0x%08x", foreground.getRGB()); + saveImage(image, fontName + "-" + hintValue + "-" + hexColor); + return "Font: " + fontName + ", Hint: " + hintValue + ", Color: " + hexColor; + } + + /** + * Verifies the rendered image of the hieroglyph. The hieroglyph + * should be stretched across the entire width of the image. + * If the right half of the image contains only pixels of the background + * color, the hieroglyph isn't stretched correctly + * — it's a failure. + * + * @param image the image to verify + * @return {@code true} if the hieroglyph is stretched correctly; or + * {@code false} if right half of the image contains only + * background-colored pixels, which means the hieroglyph isn't + * stretched. + */ + private static boolean verifyImage(final BufferedImage image) { + final int width = image.getWidth(); + final int height = image.getHeight(); + for (int x = width / 2; x < width; x++) { + for (int y = 0; y < height; y++) { + if (image.getRGB(x, y) != BACKGROUND.getRGB()) { + // Any other color but background means the glyph is stretched + return true; + } + } + } + + // The right side of the image is filled with the background color only, + // the glyph isn't stretched. + return false; + } + + private static String getHintString(final Object hint) { + if (hint == VALUE_TEXT_ANTIALIAS_OFF) { + return "off"; + } else if (hint == VALUE_TEXT_ANTIALIAS_ON) { + return "on"; + } else if (hint == VALUE_TEXT_ANTIALIAS_LCD_HRGB) { + return "lcd"; + } else { + throw new IllegalArgumentException("Unexpected hint: " + hint); + } + } + + private static final BufferedImage dummyImage = + new BufferedImage(5, 5, TYPE_3BYTE_BGR); + + private static Dimension getTextSize(final Font font) { + final Graphics g = dummyImage.getGraphics(); + try { + return g.getFontMetrics(font) + .getStringBounds(TEXT, g) + .getBounds() + .getSize(); + } finally { + g.dispose(); + } + } + + private static void saveImage(final BufferedImage image, + final String fileName) { + try { + ImageIO.write(image, + "png", + new File(fileName + ".png")); + } catch (IOException ignored) { + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/print/PageFormat/PrintContentCutOffTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, BELLSOFT. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8295737 + * @summary macOS: Print content cut off when width > height with portrait orientation + * @run main/othervm/manual PrintContentCutOffTest + */ + +import javax.swing.*; +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.font.FontRenderContext; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import java.awt.print.Book; +import java.awt.image.BufferedImage; +import java.awt.print.Paper; + +import javax.print.PrintServiceLookup; +import javax.print.attribute.Size2DSyntax; +import javax.print.attribute.standard.MediaSize; +import javax.print.attribute.standard.MediaSizeName; + + +public class PrintContentCutOffTest { + + private static final String DESCRIPTION = + + " 1. To run the test it is required to have a virtual PDF printer" + + " or any other printer supporting A4 paper size.\n" + + " 2. Press Print button to print 4 rectangles.\n" + + " - rectangle with paper width is less than height, orientation portrait\n" + + " - rectangle with paper width is less than height, orientation landscape\n" + + " - rectangle with paper width is greater than height, orientation portrait\n" + + " - rectangle with paper width is greater than height, orientation landscape\n" + + " [Note: PageFormat size returns transformed Paper size according to the set orientation value.\n" + + " 3. Check that 4 printed rectangles (one per page) have fully drawn 8 vertical areas\n" + + " labeled from 1 to 8, and that the blue diagonal lines end at the corners of the yellow rectangle.\n" + + " [Note: those are the pass/fail criteria. The messages printed in red are only informative\n" + + " and should not be used as a reason to file a bug].\n" + + " 4. If so, press PASS button, otherwise press FAIL button.\n"; + + + private static final CountDownLatch testEndedSignal = new CountDownLatch(1); + private static final int testTimeout = 300000; + private static volatile String testFailureMsg; + private static volatile boolean testPassed; + private static volatile boolean testFinished; + + private static final double DOC_WIDTH; + private static final double DOC_HEIGHT; + + static { + MediaSize isoA4Size = MediaSize.getMediaSizeForName(MediaSizeName.ISO_A4); + float[] size = isoA4Size.getSize(Size2DSyntax.INCH); + + DOC_WIDTH = size[0] * 72.0; + DOC_HEIGHT = size[1] * 72.0; + } + + private static void paintImage(Graphics2D g, PageFormat page, int pageIndex) { + BufferedImage img = createImage(page, pageIndex); + g.drawImage(img, 0, 0, null); + } + + private static void appendToBook(PrinterJob job, Book book, double width, double height, int orientation) { + + PageFormat page = job.getPageFormat(null); + page.setOrientation(orientation); + Paper paper = page.getPaper(); + + paper.setSize(width, height); + paper.setImageableArea(0, 0, width, height); + + page.setPaper(paper); + page.setOrientation(orientation); + book.append(new TestPrintable(), page); + } + + private static void print(double width, double height) throws PrinterException { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintService(PrintServiceLookup.lookupDefaultPrintService()); + + Book book = new Book(); + appendToBook(job, book, width, height, PageFormat.PORTRAIT); + appendToBook(job, book, width, height, PageFormat.LANDSCAPE); + appendToBook(job, book, height, width, PageFormat.PORTRAIT); + appendToBook(job, book, height, width, PageFormat.LANDSCAPE); + + job.setPageable(book); + + if (job.printDialog()) { + job.print(); + } else { + throw new RuntimeException("Printing was canceled!"); + } + } + + private static String getOrientation(int orientation) { + switch (orientation) { + case PageFormat.LANDSCAPE: + return "LANDSCAPE"; + case PageFormat.PORTRAIT: + return "PORTRAIT"; + case PageFormat.REVERSE_LANDSCAPE: + return "REVERSE_LANDSCAPE"; + default: + return "UNKNOWN"; + } + } + + private static BufferedImage createImage(PageFormat page, int pageIndex) { + + int w = (int) page.getWidth(); + int h = (int) page.getHeight(); + + int x = 0; + int y = 0; + + BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = img.createGraphics(); + + g.setClip(null); + + g.setColor(Color.ORANGE); + g.fillRect(x, y, w, h); + + g.setColor(Color.BLUE); + g.drawRect(x, y, w, h); + g.drawRect(x + 1, y + 1, w - 2, h - 2); + g.drawLine(x, y, x + w, y + h); + g.drawLine(x, y + h, x + w, y); + + g.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); + + int N = 8; + int dx = w / N; + + for (int i = 0; i < N; i++) { + int xx = i * dx + x; + g.setColor(Color.BLUE); + g.drawLine(xx, y, xx, y + h); + g.setColor(Color.BLUE); + g.drawString("" + (i + 1), xx + 3, y + h / 2); + } + + int NN = 5; + int arrX = x + w / 2 - 4; + g.setColor(Color.RED); + for (int i = 0; i < NN; i++) { + g.drawLine(arrX + i, y + h / 3, arrX + i, y + 2 * h / 3); + } + + int r = 7; + g.fillOval(arrX + NN / 2 - r, y + h / 3 - r - 5, 2 * r, 2 * r); + + g.setColor(Color.RED); + g.setFont(g.getFont().deriveFont(Font.BOLD, 16.0f)); + + int textX = x + w / 18; + int textY = y + h / 3; + int textDelta = h / 16; + + Paper paper = page.getPaper(); + String paperSize = String.format("Paper size: %dx%d", + (int) paper.getWidth(), (int) paper.getHeight()); + g.drawString(paperSize, textX, textY); + + String pageFormatSize = String.format("PageFormat size: %dx%d", w, h); + g.drawString(pageFormatSize, textX, textY + textDelta); + + String orientation = String.format("Orientation: %s", + getOrientation(page.getOrientation())); + g.drawString(orientation, textX, textY + 2 * textDelta); + + g.setColor(Color.BLACK); + g.setFont(g.getFont().deriveFont(28.0f)); + g.drawString(String.format("P:%d", pageIndex + 1), x + w / 2, y + 2 * h / 3); + + g.dispose(); + return img; + } + + private static class TestPrintable implements Printable { + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int index) { + paintImage((Graphics2D) graphics, pageFormat, index); + return PAGE_EXISTS; + } + } + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeLater(() -> createAndShowTestDialog()); + + try { + if (!testEndedSignal.await(testTimeout, TimeUnit.MILLISECONDS)) { + throw new RuntimeException(String.format( + "Test timeout '%d ms' elapsed.", testTimeout)); + } + if (!testPassed) { + String failureMsg = testFailureMsg; + if ((failureMsg != null) && (!failureMsg.trim().isEmpty())) { + throw new RuntimeException(failureMsg); + } else { + throw new RuntimeException("Test failed."); + } + } + } catch (InterruptedException ie) { + throw new RuntimeException(ie); + } finally { + testFinished = true; + } + } + + private static void pass() { + testPassed = true; + testEndedSignal.countDown(); + } + + private static void fail(String failureMsg) { + testFailureMsg = failureMsg; + testPassed = false; + testEndedSignal.countDown(); + } + + private static String convertMillisToTimeStr(int millis) { + if (millis < 0) { + return "00:00:00"; + } + int hours = millis / 3600000; + int minutes = (millis - hours * 3600000) / 60000; + int seconds = (millis - hours * 3600000 - minutes * 60000) / 1000; + return String.format("%02d:%02d:%02d", hours, minutes, seconds); + } + + private static void createAndShowTestDialog() { + + final JDialog dialog = new JDialog(); + dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + dialog.dispose(); + fail("Main dialog was closed."); + } + }); + + final JLabel testTimeoutLabel = new JLabel(String.format( + "Test timeout: %s", convertMillisToTimeStr(testTimeout))); + final long startTime = System.currentTimeMillis(); + final Timer timer = new Timer(0, null); + timer.setDelay(1000); + timer.addActionListener((e) -> { + int leftTime = testTimeout - (int) (System.currentTimeMillis() - startTime); + if ((leftTime < 0) || testFinished) { + timer.stop(); + dialog.dispose(); + } + testTimeoutLabel.setText(String.format( + "Test timeout: %s", convertMillisToTimeStr(leftTime))); + }); + timer.start(); + + JTextArea textArea = new JTextArea(DESCRIPTION); + textArea.setEditable(false); + + final JButton testButton = new JButton("Print"); + final JButton passButton = new JButton("PASS"); + final JButton failButton = new JButton("FAIL"); + + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + new Thread(() -> { + try { + doTest(); + + SwingUtilities.invokeLater(() -> { + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + } catch (Throwable t) { + t.printStackTrace(); + dialog.dispose(); + fail("Exception occurred in a thread executing the test."); + } + }).start(); + }); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + dialog.dispose(); + pass(); + }); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + dialog.dispose(); + fail("TitledBorder label is cut off"); + }); + + JPanel mainPanel = new JPanel(new BorderLayout()); + + JPanel labelPanel = new JPanel(new FlowLayout()); + labelPanel.add(testTimeoutLabel); + mainPanel.add(labelPanel, BorderLayout.NORTH); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + + dialog.pack(); + dialog.setVisible(true); + } + + private static void doTest() throws Exception { + SwingUtilities.invokeAndWait(() -> { + try { + print(DOC_WIDTH, DOC_HEIGHT); + } catch (PrinterException e) { + throw new RuntimeException(e); + } + }); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/print/PrinterJob/InitToBlack.java openjdk-lts-11.0.21+9/test/jdk/java/awt/print/PrinterJob/InitToBlack.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/print/PrinterJob/InitToBlack.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/print/PrinterJob/InitToBlack.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 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 @@ -22,21 +22,57 @@ */ /** + * @test * @bug 4184565 * @summary Confirm that the default foreground color on a printer * graphics object is black so that rendering will appear * without having to execute setColor first. - * @run applet/manual=yesno InitToBlack.html + * @run main/manual InitToBlack */ -import java.awt.*; -import java.awt.print.*; -import java.applet.Applet; - -public class InitToBlack extends Applet implements Printable { +import java.awt.BorderLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.print.Book; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.SwingUtilities; + +public class InitToBlack implements Printable { + + private static volatile JFrame frame; + private static volatile boolean testResult = false; + private static volatile CountDownLatch printButtonCountDownLatch = + new CountDownLatch(1); + private static volatile CountDownLatch CountDownLatch = + new CountDownLatch(1); + private static volatile String failureReason; + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + Graphics2D g2d = (Graphics2D) graphics; + g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY()); + graphics.drawString("Test Passes", 200, 200); + return PAGE_EXISTS; + } - public void init() { + private void test() { PrinterJob pjob = PrinterJob.getPrinterJob(); + if (pjob.getPrintService() == null) { + System.out.println("There is no printer configured on this system"); + return; + } Book book = new Book(); book.append(this, pjob.defaultPage()); @@ -49,17 +85,95 @@ } } - public int print(Graphics g, PageFormat pf, int pageIndex) { - Graphics2D g2d = (Graphics2D) g; - g2d.translate(pf.getImageableX(), pf.getImageableY()); - - g.drawString("Test Passes", 200, 200); + private static void createTestUI() { + frame = new JFrame("Test InitToBlack"); + String INSTRUCTION = "Aim: This test checks whether the default foreground color on a printer\n" + + "graphics object is black so that rendering will appear without having\n" + + "to execute setColor.\n" + + "Step:\n" + + "1) Click on the \"Print\" button. Check whether page is printed on the printer.\n" + + "2) Check whether \"Test Passes\" is printed on the page and it should be in\n" + + "black color. If yes then press \"Pass\" button else press \"Fail\" button.\n"; + JTextArea instructionTextArea = new JTextArea(INSTRUCTION, 4, 40); + instructionTextArea.setEditable(false); + + JPanel buttonPanel = new JPanel(); + JButton printButton = new JButton("Print"); + printButton.addActionListener((ae) -> { + InitToBlack initToBlack = new InitToBlack(); + initToBlack.test(); + printButtonCountDownLatch.countDown(); + }); + + JButton passButton = new JButton("Pass"); + passButton.addActionListener((ae) -> { + testResult = true; + CountDownLatch.countDown(); + frame.dispose(); + }); + JButton failButton = new JButton("Fail"); + failButton.addActionListener((ae) -> { + getFailureReason(); + frame.dispose(); + }); + buttonPanel.add(printButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(instructionTextArea, BorderLayout.CENTER); + panel.add(buttonPanel, BorderLayout.SOUTH); + + frame.add(panel); + frame.setLocationRelativeTo(null); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } - return PAGE_EXISTS; + public static void getFailureReason() { + final JDialog dialog = new JDialog(); + dialog.setTitle("Read testcase failure reason"); + JPanel jPanel = new JPanel(new BorderLayout()); + JTextArea jTextArea = new JTextArea(5, 20); + + JButton okButton = new JButton("Ok"); + okButton.addActionListener((ae) -> { + failureReason = jTextArea.getText(); + testResult = false; + CountDownLatch.countDown(); + dialog.dispose(); + }); + + jPanel.add(new JLabel("Enter the testcase failed reason below and " + + "click OK button", JLabel.CENTER), BorderLayout.NORTH); + jPanel.add(jTextArea, BorderLayout.CENTER); + + JPanel okayBtnPanel = new JPanel(); + okayBtnPanel.add(okButton); + + jPanel.add(okayBtnPanel, BorderLayout.SOUTH); + dialog.add(jPanel); + dialog.setLocationRelativeTo(null); + dialog.pack(); + dialog.setVisible(true); } - public static void main(String[] args) { - new InitToBlack().init(); - System.exit(0); + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(InitToBlack::createTestUI); + if (!printButtonCountDownLatch.await(2, TimeUnit.MINUTES)) { + throw new RuntimeException("Timeout: User did not perform action " + + "on Print button."); + } + if (!CountDownLatch.await(2, TimeUnit.MINUTES)) { + throw new RuntimeException("Timeout : User did not decide " + + "whether test passed or failed"); + } + + if (!testResult) { + throw new RuntimeException("Test failed : " + failureReason); + } else { + System.out.println("Test Passed"); + } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ComponentScrollTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ComponentScrollTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ComponentScrollTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ComponentScrollTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,99 @@ +/* + * 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 4342129 + @summary Unable to scroll in scrollpane for canvas + @key headful +*/ + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.ScrollPane; + +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; + +public class ComponentScrollTest { + public ScrollPane scrollpane; + public Frame frame; + public volatile int count = 0; + + public static void main(String[] args) throws Exception { + ComponentScrollTest cst = new ComponentScrollTest(); + cst.init(); + cst.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + scrollpane = new ScrollPane(); + frame = new Frame("Component Scroll Test"); + scrollpane.add(new Component() { + public Dimension getPreferredSize() { + return new Dimension(500, 500); + } + + public void paint(Graphics g) { + g.drawLine(0, 0, 500, 500); + } + }); + frame.add(scrollpane); + scrollpane.getVAdjustable().addAdjustmentListener(new AdjustmentListener() { + @Override + public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent) { + count++; + scrollpane.getVAdjustable().setValue(20); + } + }); + frame.pack(); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + scrollpane.getVAdjustable().setValue(20); + }); + + Thread.sleep(1000); + + System.out.println("Count = " + count); + if (count > 50) { + throw new RuntimeException(); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneExtraScrollBar.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneExtraScrollBar.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneExtraScrollBar.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneExtraScrollBar.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,97 @@ +/* + * 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 4152524 8310054 + @requires os.family=="windows" + @summary Test that scroll pane doesn't have scroll bars visible when it is + shown for the first time with SCROLLBARS_AS_NEEDED style + @key headful +*/ + +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.ScrollPane; + +import java.awt.event.InputEvent; + +public class ScrollPaneExtraScrollBar { + ScrollPane sp; + Frame f; + volatile Rectangle r; + + public static void main(String[] args) throws Exception { + ScrollPaneExtraScrollBar scrollTest = new ScrollPaneExtraScrollBar(); + scrollTest.init(); + scrollTest.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + f = new Frame("ScrollPaneExtraScrollBar"); + sp = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); + sp.add(new Button("TEST")); + f.add("Center", sp); + // Frame must not be packed, otherwise the bug isn't reproduced + f.setLocationRelativeTo(null); + f.setVisible(true); + }); + } + + public void start() throws Exception { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(100); + EventQueue.invokeAndWait(() -> { + r = f.getBounds(); + }); + robot.mouseMove(r.x + r.width - 1, r.y + r.height - 1); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseMove(r.x + r.width + 50, r.y + r.height + 50); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + Insets insets = sp.getInsets(); + if (insets.left != insets.right || insets.top != insets.bottom) { + throw new RuntimeException("ScrollPane has scroll bars visible" + + " when it shouldn't"); + } + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (f != null) { + f.dispose(); + } + }); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneLeakTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneLeakTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneLeakTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneLeakTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,189 @@ +/* + * 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.awt.AWTException; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.ScrollPane; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicReference; + +import static java.awt.EventQueue.invokeAndWait; + +/* + * @test + * @bug 8297923 + * @key headful + * @requires os.family=="windows" + * @summary Verifies no GDI objects are leaked after scrolling continuously + * @run main/othervm -Dsun.java2d.d3d=false ScrollPaneLeakTest + */ +public class ScrollPaneLeakTest { + + /** + * The number of times the test repeats scrolling cycles. + */ + private static final int REPEATS = 1; + + /** + * The number of times the robot moves the scroll bar thumb down and up + * per one cycle. + */ + private static final int UP_DOWN_CYCLES = 20; + + private static final Color CANVAS_FOREGROUND = new Color(200, 240, 200); + private static final Color CANVAS_BACKGROUND = new Color(240, 200, 240); + private static final Color SCROLL_PANE_BACKGROUND = new Color(240, 240, 200); + + private static final Dimension CANVAS_SIZE = new Dimension(400, 600); + private static final Dimension FRAME_SIZE = new Dimension(CANVAS_SIZE.width * 2, + 3 * CANVAS_SIZE.height / 4); + private static final Dimension SCROLL_PANE_SIZE = new Dimension(CANVAS_SIZE.width, + CANVAS_SIZE.height / 2); + + private static Frame frame; + private static ScrollPane scroll; + + private static final AtomicReference frameBounds = new AtomicReference<>(); + + private static final AtomicReference scrollBounds = new AtomicReference<>(); + + private static final AtomicReference vertBarWidth = new AtomicReference<>(); + private static final AtomicReference horzBarHeight = new AtomicReference<>(); + + public static void main(String[] args) + throws InterruptedException, InvocationTargetException, AWTException { + try { + invokeAndWait(ScrollPaneLeakTest::createUI); + + final Robot robot = new Robot(); + robot.waitForIdle(); + + invokeAndWait(() -> frame.setExtendedState(frame.getExtendedState() + | Frame.MAXIMIZED_BOTH)); + robot.waitForIdle(); + + invokeAndWait(() -> { + scrollBounds.set(new Rectangle(scroll.getLocationOnScreen(), + scroll.getSize())); + + vertBarWidth.set(scroll.getVScrollbarWidth()); + horzBarHeight.set(scroll.getHScrollbarHeight()); + }); + robot.waitForIdle(); + + invokeAndWait(() -> scroll.setScrollPosition(0, 0)); + robot.waitForIdle(); + robot.delay(1000); + + final Rectangle sb = scrollBounds.get(); + final int vbar = vertBarWidth.get(); + final int hbar = horzBarHeight.get() * 2; + + final Point pos = new Point(); + for (int no = 0; no < REPEATS; no++) { + pos.x = sb.x + sb.width - vbar / 3; + pos.y = sb.y + hbar; + + robot.mouseMove(pos.x, pos.y); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + for (int i = 0; i < UP_DOWN_CYCLES; i++) { + while (++pos.y < sb.y + sb.height - hbar) { + robot.mouseMove(pos.x, pos.y); + robot.delay(5); + } + while (--pos.y > sb.y + hbar) { + robot.mouseMove(pos.x, pos.y); + robot.delay(5); + } + } + robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK); + + invokeAndWait(() -> frame.setExtendedState(frame.getExtendedState() + | Frame.ICONIFIED)); + robot.delay(500); + invokeAndWait(() -> frame.setExtendedState(frame.getExtendedState() + & ~Frame.ICONIFIED)); + robot.delay(500); + } + + invokeAndWait(() -> scroll.setScrollPosition(0, sb.height / 2)); + + invokeAndWait(() -> { + Rectangle bounds = frame.getBounds(); + frameBounds.set(bounds); + }); + + // Throws OutOfMemoryError when the test fails + robot.createScreenCapture(frameBounds.get()); + + System.out.println("Robot created a screenshot: test passed"); + } finally { + invokeAndWait(frame::dispose); + } + } + + private static void createUI() { + frame = new Frame("Scroll Pane Leak Test"); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + + frame.setLayout(new FlowLayout(FlowLayout.CENTER)); + frame.setLocation(0, 0); + + Canvas canvas = new Canvas() { + @Override + public void paint(Graphics g) { + g.setColor(CANVAS_FOREGROUND); + g.fillRect(0, 0, getWidth(), getHeight()); + } + }; + canvas.setBackground(CANVAS_BACKGROUND); + canvas.setSize(CANVAS_SIZE); + + scroll = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); + scroll.add(canvas); + scroll.setSize(SCROLL_PANE_SIZE); + scroll.setBackground(SCROLL_PANE_BACKGROUND); + + frame.add(scroll); + frame.setSize(FRAME_SIZE); + + frame.setVisible(true); + } + +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneLimitation.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneLimitation.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneLimitation.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneLimitation.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,149 @@ +/* + * 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 4046446 + @requires os.family=="windows" + @summary Tests 16-bit limitations of scroll pane, child's position and size + and mouse coordinates + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Robot; +import java.awt.ScrollPane; + +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseAdapter; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ScrollPaneLimitation { + static final int SCROLL_POS = 50000; + public static Component child = null; + static final CountDownLatch go = new CountDownLatch(1); + public Frame frame; + volatile Point point; + ScrollPane pane; + + public static void main(String[] args) throws Exception { + ScrollPaneLimitation scrollTest = new ScrollPaneLimitation(); + scrollTest.init(); + scrollTest.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("Scroll Pane Limitation"); + frame.setLayout(new BorderLayout()); + pane = new ScrollPane(); + frame.add(pane); + child = new MyPanel(); + child.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + if (e.getID() == MouseEvent.MOUSE_PRESSED + && e.getSource() == ScrollPaneLimitation.child + && e.getY() > SCROLL_POS) { + go.countDown(); + } + } + }); + pane.add(child); + frame.setSize(200, 200); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); + frame.setVisible(true); + pane.doLayout(); + }); + } + + public void start() throws Exception { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + Point p = child.getLocation(); + System.out.println("Child's initial location " + p); + System.out.println("Pane's insets " + pane.getInsets()); + pane.setScrollPosition(0, SCROLL_POS); + p = pane.getScrollPosition(); + System.out.println("Scroll pos = " + p); + if (p.y != SCROLL_POS) { + throw new RuntimeException("wrong scroll position"); + } + p = child.getLocation(); + System.out.println("Child pos = " + p); + if (p.y != -SCROLL_POS) { + if (child.isLightweight()) { + // If it is lightweight it will always have (0, 0) location. + // Check location of its parent - it is Panel and it should + // be at (inset left, inset top + position) + Container cp = child.getParent(); + p = cp.getLocation(); + System.out.println("Child's parent pos = " + p); + if (p.y != -SCROLL_POS) { + throw new RuntimeException("wrong child location"); + } + } else { + throw new RuntimeException("wrong child location"); + } + } + + p = pane.getLocationOnScreen(); + Dimension d = pane.getSize(); + point = new Point(p.x + d.width / 2, p.y + d.height / 2); + }); + robot.mouseMove(point.x, point.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!go.await(3, TimeUnit.SECONDS)) { + throw new RuntimeException("mouse was not pressed"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + private static class MyPanel extends Component { + public Dimension getPreferredSize() { + return new Dimension(100, 100000); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneRemoveAdd.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneRemoveAdd.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneRemoveAdd.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneRemoveAdd.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,113 @@ +/* + * 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 4100671 + @summary Tests that after removing/adding a component can be still access. + @key headful +*/ + +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.ScrollPane; + +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class ScrollPaneRemoveAdd { + Button button; + ScrollPane pane; + Frame frame; + volatile Point buttonLoc; + volatile Dimension buttonSize; + volatile CountDownLatch latch; + + public static void main(String[] args) throws Exception { + ScrollPaneRemoveAdd scrollTest = new ScrollPaneRemoveAdd(); + scrollTest.init(); + scrollTest.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("Scroll pane Add/Remove"); + pane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); + button = new Button("press"); + latch = new CountDownLatch(1); + + pane.add(button); + frame.add(pane); + + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + latch.countDown(); + } + }); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + pane.remove(0); + pane.add(button); + buttonLoc = button.getLocationOnScreen(); + buttonSize = button.getSize(); + }); + + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + robot.mouseMove(buttonLoc.x + buttonSize.width / 2, + buttonLoc.y + buttonSize.height / 2); + robot.delay(50); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.delay(50); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!latch.await(1, TimeUnit.SECONDS)) { + throw new RuntimeException("ScrollPane doesn't handle " + + "correctly add after remove"); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneScrollEnd.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneScrollEnd.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneScrollEnd.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneScrollEnd.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * 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.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Robot; +import java.awt.ScrollPane; + +/* + * @test + * @bug 8311689 + * @key headful + * @requires os.family=="windows" + * @summary Verifies ScrollPane allows viewing the whole contents of its child + * @run main ScrollPaneScrollEnd + */ +public final class ScrollPaneScrollEnd { + private static final Color CANVAS_BACKGROUND = new Color(255, 200, 200); + private static final Color CANVAS_FOREGROUND = new Color(255, 255, 200); + private static final int OFFSET = 12; + + private static final Dimension CANVAS_SIZE = new Dimension(900, 600); + private static final Dimension SCROLL_PANE_SIZE = + new Dimension(CANVAS_SIZE.width / 3, CANVAS_SIZE.height / 3); + private static final int SCROLL_OFFSET = 100; + + private static final int DELAY = 200; + + public static void main(String[] args) throws Exception { + Canvas canvas = new Canvas() { + @Override + public void paint(Graphics g) { + g.setColor(CANVAS_BACKGROUND); + g.fillRect(0, 0, getWidth(), getHeight()); + + g.setColor(CANVAS_FOREGROUND); + g.fillRect(OFFSET, OFFSET, + getWidth() - OFFSET * 2, getHeight() - OFFSET * 2); + } + }; + canvas.setSize(CANVAS_SIZE); + + ScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); + scrollPane.add(canvas); + scrollPane.setSize(SCROLL_PANE_SIZE); + + Frame frame = new Frame("ScrollPaneScrollEnd"); + frame.add(scrollPane, "Center"); + frame.setLocation(100, 100); + frame.pack(); + frame.setVisible(true); + + final Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(DELAY); + + final Dimension vp = scrollPane.getViewportSize(); + final Point expected = new Point(CANVAS_SIZE.width - vp.width, + CANVAS_SIZE.height - vp.height); + + scrollPane.setScrollPosition(CANVAS_SIZE.width + SCROLL_OFFSET, + CANVAS_SIZE.height + SCROLL_OFFSET); + try { + if (!expected.equals(scrollPane.getScrollPosition())) { + throw new Error("Can't scroll to the end of the child component"); + } + } finally { + frame.dispose(); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneWindowsTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneWindowsTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPaneWindowsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPaneWindowsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,191 @@ +/* + * 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 4452612 + @requires os.family=="windows" + @summary The popup menu of the scroll bar doesn't work properly in Window2000. + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Insets; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.ScrollPane; +import java.awt.ScrollPaneAdjustable; + +import java.awt.event.AdjustmentListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +public class ScrollPaneWindowsTest implements AdjustmentListener { + ScrollPane sp; + Panel p; + Robot robot; + Frame frame; + Insets paneInsets; + public static final Object LOCK = new Object(); + ScrollPaneAdjustable vScroll; + ScrollPaneAdjustable hScroll; + boolean notifyReceived = false; + volatile int xPos = 0; + volatile int yPos = 0; + + public static void main(String[] args) throws Exception { + ScrollPaneWindowsTest scrollTest = new ScrollPaneWindowsTest(); + scrollTest.init(); + scrollTest.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("ScrollPaneWindowsTest"); + frame.setLayout(new BorderLayout(1, 1)); + p = new Panel(); + p.setLayout(null); + p.setSize(new Dimension(800, 800)); + sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); + vScroll = (ScrollPaneAdjustable) sp.getVAdjustable(); + hScroll = (ScrollPaneAdjustable) sp.getHAdjustable(); + vScroll.addAdjustmentListener(ScrollPaneWindowsTest.this); + hScroll.addAdjustmentListener(ScrollPaneWindowsTest.this); + sp.add(p); + frame.add(sp); + frame.pack(); + frame.setSize(400, 400); + frame.setLocationRelativeTo(null); + frame.setAlwaysOnTop(true); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + try { + EventQueue.invokeAndWait(() -> { + paneInsets = sp.getInsets(); + System.out.println("Insets: right = " + paneInsets.right + " bottom = " + paneInsets.bottom); + }); + + robot = new Robot(); + robot.waitForIdle(); + robot.delay(100); + + EventQueue.invokeAndWait(() -> { + xPos = sp.getLocationOnScreen().x + sp.getWidth() - paneInsets.right / 2; + yPos = sp.getLocationOnScreen().y + sp.getHeight() / 2; + }); + + robot.mouseMove(xPos, yPos); + testOneScrollbar(vScroll); + + robot.waitForIdle(); + robot.delay(100); + + EventQueue.invokeAndWait(() -> { + xPos = sp.getLocationOnScreen().x + sp.getWidth() / 2; + yPos = sp.getLocationOnScreen().y + sp.getHeight() - paneInsets.bottom / 2; + }); + + robot.mouseMove(xPos, yPos); + testOneScrollbar(hScroll); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + System.out.println("Test passed. "); + } + + public void testOneScrollbar(ScrollPaneAdjustable scroll) throws Exception { + //to Bottom - right + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + robot.waitForIdle(); + robot.delay(2000); + + synchronized (LOCK) { + notifyReceived = false; + for (int i = 0; i < 3; i++) { + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + } + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + if (!notifyReceived) { + System.out.println("we are waiting 1"); + LOCK.wait(2000); + } + if (scroll.getValue() + scroll.getVisibleAmount() != scroll.getMaximum()) { + System.out.println("scroll.getValue() = " + scroll.getValue()); + System.out.println("scroll.getVisibleAmount() = " + scroll.getVisibleAmount()); + System.out.println("scroll.getMaximum() = " + scroll.getMaximum()); + throw new RuntimeException("Test Failed. Position of scrollbar is incorrect."); + } else { + System.out.println("Test stage 1 passed."); + } + notifyReceived = false; + } + + //to top-left + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + robot.waitForIdle(); + robot.delay(2000); + + synchronized (LOCK) { + for (int i = 0; i < 2; i++) { + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + } + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + if (!notifyReceived) { + System.out.println("we are waiting 2"); + LOCK.wait(2000); + } + if (scroll.getValue() != 0) { + System.out.println("scroll.getValue() = " + scroll.getValue()); + throw new RuntimeException("Test Failed. Position of scrollbar is incorrect."); + } else { + System.out.println("Test stage 2 passed."); + } + } + } + + @Override + public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent) { + synchronized (ScrollPaneWindowsTest.LOCK) { + notifyReceived = true; + ScrollPaneWindowsTest.LOCK.notify(); + } + System.out.println("Adjustment Event called "); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPositionIntact.java openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPositionIntact.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/ScrollPane/ScrollPositionIntact.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/ScrollPane/ScrollPositionIntact.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 6404832 + @summary Tests that scroll position is not changed by validate() for mode SCROLLBARS_NEVER + @key headful + @run main ScrollPositionIntact +*/ + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.ScrollPane; + +public class ScrollPositionIntact { + Frame frame; + ScrollPane sp; + Panel pa; + public static final int X_POS = 100; + + public static void main(String[] args) throws Exception { + ScrollPositionIntact test = new ScrollPositionIntact(); + test.init(); + test.start(); + } + + public void init() throws Exception { + EventQueue.invokeAndWait(() -> { + pa = new Panel(); + pa.setSize(600, 50); + pa.setPreferredSize(new Dimension(600, 50)); + pa.setBackground(Color.red); + sp = new ScrollPane(ScrollPane.SCROLLBARS_NEVER); + sp.setSize(200, 50); + pa.setLayout(new GridLayout(1, 3)); + pa.add("West", new Label("west", Label.LEFT)); + pa.add("West", new Label()); + pa.add("East", new Label("East", Label.RIGHT)); + sp.add(pa); + frame = new Frame("ScrollPositionIntact"); + frame.setSize(200, 100); + frame.add(sp); + frame.setVisible(true); + }); + } + + public void start() throws Exception { + try { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + frame.toFront(); + frame.requestFocus(); + + sp.setScrollPosition(X_POS, sp.getScrollPosition().y); + pa.validate(); + // Now, before the fix, in Windows XP, Windows XP theme and on Vista, + // scrollposition would be reset to zero.. + sp.validate(); + + int i = (int) (sp.getScrollPosition().getX()); + if (i <= 0) { + // actual position MAY be not equal to X_POS; still, it must be > 0. + throw new RuntimeException("Test failure: zero scroll position.\n\n"); + } + }); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Toolkit/ToolkitListenerTest/ToolkitListenerTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,126 @@ +/* + * 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 4460376 + @summary we should create Component-, Container- and HierarchyEvents if + appropriate AWTEventListener added on Toolkit + @key headful +*/ + +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.ComponentEvent; +import java.awt.event.ContainerEvent; +import java.awt.event.HierarchyEvent; +import java.lang.reflect.InvocationTargetException; + +public class ToolkitListenerTest implements AWTEventListener +{ + public static Frame frame; + static boolean containerEventReceived = false; + static boolean componentEventReceived = false; + static boolean hierarchyEventReceived = false; + static boolean hierarchyBoundsEventReceived = false; + + public static void main(String[] args) throws Exception { + ToolkitListenerTest test = new ToolkitListenerTest(); + test.start(); + } + public void start() throws Exception { + Toolkit.getDefaultToolkit(). + addAWTEventListener(this, + AWTEvent.COMPONENT_EVENT_MASK | + AWTEvent.CONTAINER_EVENT_MASK | + AWTEvent.HIERARCHY_EVENT_MASK | + AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK); + EventQueue.invokeAndWait(() -> { + frame = new Frame("ToolkitListenerTest"); + frame.setSize(200, 200); + frame.add(new Button()); + frame.setBounds(100, 100, 100, 100); + }); + try { + Toolkit.getDefaultToolkit().getSystemEventQueue(). + invokeAndWait(new Runnable() { + public void run() {} + }); + + EventQueue.invokeAndWait(() -> { + if (!componentEventReceived) { + throw new RuntimeException("Test Failed: ComponentEvent " + + "was not dispatched"); + } + if (!containerEventReceived) { + throw new RuntimeException("Test Failed: ContainerEvent " + + "was not dispatched"); + } + if (!hierarchyEventReceived) { + throw new RuntimeException("Test Failed: " + + "HierarchyEvent(HIERARCHY_CHANGED) was not dispatched"); + } + if (!hierarchyBoundsEventReceived) { + throw new RuntimeException("Test Failed: " + + "HierarchyEvent(ANCESTOR_MOVED or ANCESTOR_RESIZED) " + + "was not dispatched"); + } + }); + } catch (InterruptedException ie) { + throw new RuntimeException("Test Failed: InterruptedException " + + "accured."); + } catch (InvocationTargetException ite) { + throw new RuntimeException("Test Failed: " + + "InvocationTargetException accured."); + } finally { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public void eventDispatched(AWTEvent e) { + System.err.println(e); + if (e instanceof ContainerEvent) { + containerEventReceived = true; + } else if (e instanceof ComponentEvent) { + componentEventReceived = true; + } else if (e instanceof HierarchyEvent) { + switch (e.getID()) { + case HierarchyEvent.HIERARCHY_CHANGED: + hierarchyEventReceived = true; + break; + case HierarchyEvent.ANCESTOR_MOVED: + case HierarchyEvent.ANCESTOR_RESIZED: + hierarchyBoundsEventReceived = true; + break; + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java openjdk-lts-11.0.21+9/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -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,142 +21,236 @@ * questions. */ -/** +/* * @test * @key headful - * @summary setAlwaysOnTop doesn't behave correctly in Linux/Solaris under - * certain scenarios * @bug 8021961 - * @author Semyon Sadetsky + * @summary To test setAlwaysOnTop functionality. * @run main/othervm -Dsun.java2d.uiScale=1 ChildAlwaysOnTopTest */ -import javax.swing.*; -import java.awt.*; +import java.awt.Color; +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.Window; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; + +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.SwingUtilities; public class ChildAlwaysOnTopTest { private static Window win1; private static Window win2; private static Point point; + private static Robot robot; + private static int caseNo = 0; + private static StringBuffer errorLog = new StringBuffer(); + private static String[] errorMsg= new String[] { + " Scenario 1 Failed: alwaysOnTop window is sent back by another" + + " child window with setVisible().", + " Scenario 2 Failed: alwaysOnTop window is" + + " sent back by another child window with toFront().", + " Scenario 3 Failed: Failed to unset alwaysOnTop ", + }; public static void main(String[] args) throws Exception { - if( Toolkit.getDefaultToolkit().isAlwaysOnTopSupported() ) { + if (!Toolkit.getDefaultToolkit().isAlwaysOnTopSupported()) { + System.out.println("alwaysOnTop not supported by: "+ + Toolkit.getDefaultToolkit().getClass().getName()); + return; + } - test(null); + // CASE 1 - JDialog without parent/owner + System.out.println("Testing CASE 1: JDialog without parent/owner"); + caseNo = 1; + test(null); + System.out.println("CASE 1 Completed"); + System.out.println(); + + // CASE 2 - JDialog with JFrame as owner + System.out.println("Testing CASE 2: JDialog with JFrame as owner"); + caseNo = 2; + Window f = new Frame(); + f.setBackground(Color.darkGray); + f.setSize(500, 500); + try { + test(f); + } finally { + f.dispose(); + } + System.out.println("CASE 2 Completed"); + System.out.println(); - Window f = new Frame(); - f.setBackground(Color.darkGray); - f.setSize(500, 500); - try { - test(f); - } finally { - f.dispose(); - } + // CASE 3 - JDialog within another JDialog as owner + System.out.println("Testing CASE 3:Dialog within another"+ + " JDialog as owner"); + caseNo = 3; + f = new Frame(); + f.setBackground(Color.darkGray); + f.setSize(500, 500); + f.setVisible(true); + f = new Dialog((Frame)f); + try { + test(f); + } finally { + ((Frame)f.getParent()).dispose(); + } + System.out.println("CASE 3 Completed"); + System.out.println(); - f = new Frame(); - f.setBackground(Color.darkGray); - f.setSize(500, 500); - f.setVisible(true); - f = new Dialog((Frame)f); - try { - test(f); - } finally { - ((Frame)f.getParent()).dispose(); - } + if (errorLog.length() == 0) { + System.out.println("All three cases passed !!"); + } + else { + throw new RuntimeException("Following cases and scenarios failed."+ + " Please check the saved screenshots.\n"+ errorLog); } - System.out.println("ok"); } public static void test(Window parent) throws Exception { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - win1 = parent == null ? new JDialog() : new JDialog(parent); - win1.setName("top"); - win2 = parent == null ? new JDialog() : new JDialog(parent); - win2.setName("behind"); - win1.setSize(200, 200); - Panel panel = new Panel(); - panel.setBackground(Color.GREEN); - win1.add(panel); - panel = new Panel(); - panel.setBackground(Color.RED); - win2.add(panel); - win1.setAlwaysOnTop(true); - win2.setAlwaysOnTop(false); - win1.setVisible(true); - } - }); + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win1 = parent == null ? new JDialog() : new JDialog(parent); + win1.setName("Top"); + + win2 = parent == null ? new JDialog() : new JDialog(parent); + win2.setName("Behind"); + + JLabel label = new JLabel("TOP WINDOW"); + // top window - green and smaller + win1.setSize(200, 200); + Panel panel = new Panel(); + panel.setBackground(Color.GREEN); + panel.add(label); + win1.add(panel); + win1.setAlwaysOnTop(true); + + // behind window - red and bigger + label = new JLabel("BEHIND WINDOW"); + win2.setSize(300, 300); + panel = new Panel(); + panel.setBackground(Color.RED); + panel.add(label); + win2.add(panel); - Robot robot = new Robot(); - robot.delay(500); - robot.waitForIdle(); + win1.setVisible(true); + win2.setVisible(true); + } + }); - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { + robot = new Robot(); + robot.setAutoDelay(300); + robot.waitForIdle(); + + // Scenario 1: Trying to unset the alwaysOnTop (green window) + // by setting the setVisible to true for behind (red) window + System.out.println(" >> Testing Scenario 1 ..."); + SwingUtilities.invokeAndWait(()-> { point = win1.getLocationOnScreen(); - win2.setBounds(win1.getBounds()); win2.setVisible(true); - } - }); + }); - robot.delay(500); - robot.waitForIdle(); + checkTopWindow(caseNo, 1, Color.GREEN); - Color color = robot.getPixelColor(point.x + 100, point.y + 100); - if(!color.equals(Color.GREEN)) { - win1.dispose(); - win2.dispose(); - throw new RuntimeException("alawaysOnTop window is sent back by " + - "another child window setVisible(). " + color); - } + /*---------------------------------------------------------------*/ - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { + // Scenario 2: Trying to unset the alwaysOnTop (green window) + // by setting toFront() to true for behind (red) window + System.out.println(" >> Testing Scenario 2 ..."); + SwingUtilities.invokeAndWait(()-> { win2.toFront(); if (parent != null) { parent.setLocation(win1.getLocation()); parent.toFront(); } - } - }); + }); - robot.delay(500); - robot.waitForIdle(); + checkTopWindow(caseNo, 2, Color.GREEN); - color = robot.getPixelColor(point.x + 100, point.y + 100); - if(!color.equals(Color.GREEN)) { - win1.dispose(); - win2.dispose(); - throw new RuntimeException("alawaysOnTop window is sent back by " + - "another child window toFront(). " + color); - } + /*----------------------------------------------------------------*/ - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - win1.setAlwaysOnTop(false); - if (parent != null) { - parent.setVisible(false); - parent.setVisible(true); + // Scenario 3: Trying to unset the alwaysOnTop (green window) + // by setting alwaysOnTop to false. The unsetting should work + // in this case and bring the red window to the top. + System.out.println(" >> Testing Scenario 3 ..."); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win1.setAlwaysOnTop(false); + if (parent != null) { + parent.setVisible(false); + parent.setVisible(true); + } } - win2.toFront(); + }); + + robot.delay(300); + robot.waitForIdle(); + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + win2.toFront(); + } + }); + + checkTopWindow(caseNo, 3, Color.RED); + + } finally { + if (win1 != null) { + SwingUtilities.invokeAndWait(()-> win1.dispose()); + } + if (win2 != null) { + SwingUtilities.invokeAndWait(()-> win2.dispose()); } - }); + } + } + // to check if the current top window background color + // matches the expected color + private static void checkTopWindow(int caseNo, int scenarioNo, + Color expectedColor) { robot.delay(500); robot.waitForIdle(); + Color actualColor = robot.getPixelColor(point.x + 100, point.y + 100); - color = robot.getPixelColor(point.x + 100, point.y + 100); - if(!color.equals(Color.RED)) { - throw new RuntimeException("Failed to unset alawaysOnTop " + color); + saveScreenCapture(caseNo , scenarioNo); + + if (!actualColor.equals(expectedColor)) { + System.out.println(" >> Scenario "+ scenarioNo +" FAILED !!"); + errorLog.append("Case "+ caseNo + errorMsg[scenarioNo - 1] + +" Expected Color: "+ expectedColor +" vs Actual Color: " + + actualColor +"\n"); + } + else { + System.out.println(" >> Scenario "+ scenarioNo +" Passed"); } + } - win1.dispose(); - win2.dispose(); + // For Debugging purpose - method used to save the screen capture as + // BufferedImage in the event the test fails + private static void saveScreenCapture(int caseNo, int scenarioNo) { + String filename = "img_"+ caseNo +"_"+ scenarioNo; + BufferedImage image = robot.createScreenCapture( + new Rectangle(0, 0, 500, 500)); + try { + ImageIO.write(image, "png", new File(filename)); + } catch (IOException e) { + e.printStackTrace(); + } } -} +} \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/io/ByteArrayOutputStream/MaxCapacity.java openjdk-lts-11.0.21+9/test/jdk/java/io/ByteArrayOutputStream/MaxCapacity.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/io/ByteArrayOutputStream/MaxCapacity.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/io/ByteArrayOutputStream/MaxCapacity.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,6 @@ /* - * Copyright (c) 2014 Google Inc. All rights reserved. + * Copyright (c) 2014, Google Inc. All rights reserved. + * Copyright (c) 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 @@ -23,11 +24,11 @@ /* * @test - * @ignore This test has huge memory requirements - * @run main/timeout=1800/othervm -Xmx8g MaxCapacity * @bug 8055949 * @summary Check that we can write (almost) Integer.MAX_VALUE bytes * to a ByteArrayOutputStream. + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 10g) + * @run main/timeout=1800/othervm -Xmx8g MaxCapacity * @author Martin Buchholz */ import java.io.ByteArrayOutputStream; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/io/File/MacPath.java openjdk-lts-11.0.21+9/test/jdk/java/io/File/MacPath.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/io/File/MacPath.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/io/File/MacPath.java 2023-10-06 05:33:33.000000000 +0000 @@ -38,7 +38,7 @@ public class MacPath { public static void main(String args[]) throws Exception { final ProcessBuilder pb = - ProcessTools.createJavaProcessBuilder(true, MacPathTest.class.getName()); + ProcessTools.createTestJvm(MacPathTest.class.getName()); final Map env = pb.environment(); env.put("LC_ALL", "en_US.UTF-8"); Process p = ProcessTools.startProcess("Mac Path Test", pb); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/io/File/SetLastModified.java openjdk-lts-11.0.21+9/test/jdk/java/io/File/SetLastModified.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/io/File/SetLastModified.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/io/File/SetLastModified.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -23,6 +23,7 @@ /* @test @bug 4091757 6652379 8177809 + @requires os.maxMemory >= 16G @summary Basic test for setLastModified method */ diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/io/Serializable/evolution/RenamePackage/RenamePackageTest.java openjdk-lts-11.0.21+9/test/jdk/java/io/Serializable/evolution/RenamePackage/RenamePackageTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/io/Serializable/evolution/RenamePackage/RenamePackageTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/io/Serializable/evolution/RenamePackage/RenamePackageTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -81,7 +81,7 @@ } private static void runTestSerialDriver() throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-classpath", SHARE.toString() + File.pathSeparator @@ -93,7 +93,7 @@ } private static void runInstallSerialDriver() throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-classpath", SHARE.toString() + File.pathSeparator diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java openjdk-lts-11.0.21+9/test/jdk/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/instrument/DaemonThread/TestDaemonThreadLauncher.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,7 +29,7 @@ public class TestDaemonThreadLauncher { public static void main(String args[]) throws Exception { for(int i=0; i<50; i++) { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-javaagent:DummyAgent.jar", "TestDaemonThread", "."); + ProcessBuilder pb = ProcessTools.createTestJvm("-javaagent:DummyAgent.jar", "TestDaemonThread", "."); OutputAnalyzer analyzer = ProcessTools.executeProcess(pb); analyzer.shouldNotContain("ASSERTION FAILED"); analyzer.shouldHaveExitValue(0); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -443,9 +443,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); + boolean x = (boolean) vh.get(recv); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -453,9 +460,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); + boolean x = (boolean) vh.get(recv); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -463,9 +477,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); + boolean x = (boolean) vh.get(recv); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, true, false); + assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); } { @@ -473,9 +494,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) vh.get(recv); - assertEquals(x, true, "weakCompareAndSet boolean value"); + assertEquals(x, true, "success weakCompareAndSet boolean value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); + boolean x = (boolean) vh.get(recv); + assertEquals(x, true, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -703,9 +731,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); + boolean x = (boolean) vh.get(); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -713,9 +748,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); + boolean x = (boolean) vh.get(); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -723,9 +765,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = vh.weakCompareAndSetRelease(true, false); + assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); + boolean x = (boolean) vh.get(); + assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); } { @@ -733,9 +782,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); + boolean x = (boolean) vh.get(); + assertEquals(x, true, "success weakCompareAndSet boolean"); + } + + { + boolean success = vh.weakCompareAndSet(false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) vh.get(); - assertEquals(x, true, "weakCompareAndSet boolean"); + assertEquals(x, true, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -966,9 +1022,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); + boolean x = (boolean) vh.get(array, i); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -976,9 +1039,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); + boolean x = (boolean) vh.get(array, i); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -986,9 +1056,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); + boolean x = (boolean) vh.get(array, i); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, true, false); + assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); } { @@ -996,9 +1073,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); + boolean x = (boolean) vh.get(array, i); + assertEquals(x, true, "success weakCompareAndSet boolean"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) vh.get(array, i); - assertEquals(x, true, "weakCompareAndSet boolean"); + assertEquals(x, true, "failing weakCompareAndSet boolean value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -421,9 +421,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -431,9 +438,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -441,9 +455,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); } { @@ -451,9 +472,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) vh.get(recv); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte value"); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -697,9 +725,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain((byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); + byte x = (byte) vh.get(); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = vh.weakCompareAndSetPlain((byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -707,9 +742,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire((byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); + byte x = (byte) vh.get(); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = vh.weakCompareAndSetAcquire((byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -717,9 +759,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease((byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = vh.weakCompareAndSetRelease((byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetRelease byte"); + byte x = (byte) vh.get(); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); } { @@ -727,9 +776,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet((byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); + byte x = (byte) vh.get(); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + } + + { + boolean success = vh.weakCompareAndSet((byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) vh.get(); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -976,9 +1032,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); + byte x = (byte) vh.get(array, i); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -986,9 +1049,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); + byte x = (byte) vh.get(array, i); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -996,9 +1066,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); + byte x = (byte) vh.get(array, i); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); } { @@ -1006,9 +1083,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); + byte x = (byte) vh.get(array, i); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) vh.get(array, i); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -421,9 +421,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); + char x = (char) vh.get(recv); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -431,9 +438,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); + char x = (char) vh.get(recv); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -441,9 +455,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); + char x = (char) vh.get(recv); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) vh.get(recv); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); } { @@ -451,9 +472,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) vh.get(recv); - assertEquals(x, '\u0123', "weakCompareAndSet char value"); + assertEquals(x, '\u0123', "success weakCompareAndSet char value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); + char x = (char) vh.get(recv); + assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); } // Compare set and get @@ -697,9 +725,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain('\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); + char x = (char) vh.get(); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = vh.weakCompareAndSetPlain('\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -707,9 +742,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire('\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); + char x = (char) vh.get(); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = vh.weakCompareAndSetAcquire('\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -717,9 +759,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease('\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) vh.get(); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = vh.weakCompareAndSetRelease('\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetRelease char"); + char x = (char) vh.get(); + assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); } { @@ -727,9 +776,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet('\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); + char x = (char) vh.get(); + assertEquals(x, '\u0123', "success weakCompareAndSet char"); + } + + { + boolean success = vh.weakCompareAndSet('\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) vh.get(); - assertEquals(x, '\u0123', "weakCompareAndSet char"); + assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); } // Compare set and get @@ -976,9 +1032,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); + char x = (char) vh.get(array, i); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -986,9 +1049,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); + char x = (char) vh.get(array, i); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -996,9 +1066,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); + char x = (char) vh.get(array, i); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); } { @@ -1006,9 +1083,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); + char x = (char) vh.get(array, i); + assertEquals(x, '\u0123', "success weakCompareAndSet char"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) vh.get(array, i); - assertEquals(x, '\u0123', "weakCompareAndSet char"); + assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -491,9 +491,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); + double x = (double) vh.get(recv); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -501,9 +508,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = (double) vh.get(recv); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -511,9 +525,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); + double x = (double) vh.get(recv); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) vh.get(recv); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); } { @@ -521,9 +542,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) vh.get(recv); - assertEquals(x, 1.0d, "weakCompareAndSet double value"); + assertEquals(x, 1.0d, "success weakCompareAndSet double value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); + double x = (double) vh.get(recv); + assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); } // Compare set and get @@ -719,9 +747,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); + double x = (double) vh.get(); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -729,9 +764,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = (double) vh.get(); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -739,9 +781,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = vh.weakCompareAndSetRelease(1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); + double x = (double) vh.get(); + assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); } { @@ -749,9 +798,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = (double) vh.get(); + assertEquals(x, 1.0d, "success weakCompareAndSet double"); + } + + { + boolean success = vh.weakCompareAndSet(2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(); - assertEquals(x, 1.0d, "weakCompareAndSet double"); + assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); } // Compare set and get @@ -950,9 +1006,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); + double x = (double) vh.get(array, i); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -960,9 +1023,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); + double x = (double) vh.get(array, i); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -970,9 +1040,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); + double x = (double) vh.get(array, i); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); } { @@ -980,9 +1057,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, 1.0d, "success weakCompareAndSet double"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, 1.0d, "weakCompareAndSet double"); + assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -491,9 +491,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); + float x = (float) vh.get(recv); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -501,9 +508,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = (float) vh.get(recv); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -511,9 +525,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); + float x = (float) vh.get(recv); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) vh.get(recv); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); } { @@ -521,9 +542,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) vh.get(recv); - assertEquals(x, 1.0f, "weakCompareAndSet float value"); + assertEquals(x, 1.0f, "success weakCompareAndSet float value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); + float x = (float) vh.get(recv); + assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); } // Compare set and get @@ -719,9 +747,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); + float x = (float) vh.get(); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -729,9 +764,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = (float) vh.get(); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -739,9 +781,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = vh.weakCompareAndSetRelease(1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); + float x = (float) vh.get(); + assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); } { @@ -749,9 +798,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = (float) vh.get(); + assertEquals(x, 1.0f, "success weakCompareAndSet float"); + } + + { + boolean success = vh.weakCompareAndSet(2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(); - assertEquals(x, 1.0f, "weakCompareAndSet float"); + assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); } // Compare set and get @@ -950,9 +1006,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); + float x = (float) vh.get(array, i); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -960,9 +1023,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); + float x = (float) vh.get(array, i); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -970,9 +1040,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); + float x = (float) vh.get(array, i); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); } { @@ -980,9 +1057,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, 1.0f, "success weakCompareAndSet float"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, 1.0f, "weakCompareAndSet float"); + assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -421,9 +421,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); + int x = (int) vh.get(recv); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -431,9 +438,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = (int) vh.get(recv); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -441,9 +455,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); + int x = (int) vh.get(recv); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) vh.get(recv); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); } { @@ -451,9 +472,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) vh.get(recv); - assertEquals(x, 0x01234567, "weakCompareAndSet int value"); + assertEquals(x, 0x01234567, "success weakCompareAndSet int value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); + int x = (int) vh.get(recv); + assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); } // Compare set and get @@ -697,9 +725,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); + int x = (int) vh.get(); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -707,9 +742,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = (int) vh.get(); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -717,9 +759,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = vh.weakCompareAndSetRelease(0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); + int x = (int) vh.get(); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); } { @@ -727,9 +776,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = (int) vh.get(); + assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + } + + { + boolean success = vh.weakCompareAndSet(0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(); - assertEquals(x, 0x01234567, "weakCompareAndSet int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); } // Compare set and get @@ -976,9 +1032,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); + int x = (int) vh.get(array, i); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -986,9 +1049,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -996,9 +1066,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); } { @@ -1006,9 +1083,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, 0x01234567, "weakCompareAndSet int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -421,9 +421,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); + long x = (long) vh.get(recv); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -431,9 +438,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = (long) vh.get(recv); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -441,9 +455,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); + long x = (long) vh.get(recv); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) vh.get(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); } { @@ -451,9 +472,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) vh.get(recv); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long value"); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); + long x = (long) vh.get(recv); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); } // Compare set and get @@ -697,9 +725,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); + long x = (long) vh.get(); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -707,9 +742,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = (long) vh.get(); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -717,9 +759,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = vh.weakCompareAndSetRelease(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); + long x = (long) vh.get(); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); } { @@ -727,9 +776,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = (long) vh.get(); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + } + + { + boolean success = vh.weakCompareAndSet(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); } // Compare set and get @@ -976,9 +1032,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); + long x = (long) vh.get(array, i); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -986,9 +1049,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -996,9 +1066,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); } { @@ -1006,9 +1083,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -421,9 +421,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); + short x = (short) vh.get(recv); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -431,9 +438,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); + short x = (short) vh.get(recv); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -441,9 +455,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); + short x = (short) vh.get(recv); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); } { @@ -451,9 +472,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) vh.get(recv); - assertEquals(x, (short)0x0123, "weakCompareAndSet short value"); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); + short x = (short) vh.get(recv); + assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); } // Compare set and get @@ -697,9 +725,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain((short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); + short x = (short) vh.get(); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = vh.weakCompareAndSetPlain((short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -707,9 +742,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire((short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); + short x = (short) vh.get(); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = vh.weakCompareAndSetAcquire((short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -717,9 +759,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease((short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) vh.get(); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = vh.weakCompareAndSetRelease((short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetRelease short"); + short x = (short) vh.get(); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); } { @@ -727,9 +776,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet((short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); + short x = (short) vh.get(); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + } + + { + boolean success = vh.weakCompareAndSet((short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) vh.get(); - assertEquals(x, (short)0x0123, "weakCompareAndSet short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); } // Compare set and get @@ -976,9 +1032,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); + short x = (short) vh.get(array, i); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -986,9 +1049,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); + short x = (short) vh.get(array, i); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -996,9 +1066,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); + short x = (short) vh.get(array, i); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); } { @@ -1006,9 +1083,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); + short x = (short) vh.get(array, i); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) vh.get(array, i); - assertEquals(x, (short)0x0123, "weakCompareAndSet short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessString.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -520,9 +520,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain String"); + assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "weakCompareAndSetPlain String value"); + assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain String"); + String x = (String) vh.get(recv); + assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); } { @@ -530,9 +537,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire String"); + assertEquals(success, true, "success weakCompareAndSetAcquire String"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { @@ -540,9 +554,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease String"); + assertEquals(success, true, "success weakCompareAndSetRelease String"); + String x = (String) vh.get(recv); + assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) vh.get(recv); - assertEquals(x, "bar", "weakCompareAndSetRelease String"); + assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); } { @@ -550,9 +571,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet String"); + assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) vh.get(recv); - assertEquals(x, "foo", "weakCompareAndSet String value"); + assertEquals(x, "foo", "success weakCompareAndSet String value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet String"); + String x = (String) vh.get(recv); + assertEquals(x, "foo", "failing weakCompareAndSet String value"); } // Compare set and get @@ -732,9 +760,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain("foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain String"); + assertEquals(success, true, "success weakCompareAndSetPlain String"); + String x = (String) vh.get(); + assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + } + + { + boolean success = vh.weakCompareAndSetPlain("foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) vh.get(); - assertEquals(x, "bar", "weakCompareAndSetPlain String value"); + assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); } { @@ -742,9 +777,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire("bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire String"); + assertEquals(success, true, "success weakCompareAndSetAcquire String"); + String x = (String) vh.get(); + assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + } + + { + boolean success = vh.weakCompareAndSetAcquire("bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) vh.get(); - assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { @@ -752,9 +794,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease("foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease String"); + assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) vh.get(); - assertEquals(x, "bar", "weakCompareAndSetRelease String"); + assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + } + + { + boolean success = vh.weakCompareAndSetRelease("foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetRelease String"); + String x = (String) vh.get(); + assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); } { @@ -762,9 +811,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet("bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet String"); + assertEquals(success, true, "success weakCompareAndSet String"); + String x = (String) vh.get(); + assertEquals(x, "foo", "success weakCompareAndSet String"); + } + + { + boolean success = vh.weakCompareAndSet("bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) vh.get(); - assertEquals(x, "foo", "weakCompareAndSet String"); + assertEquals(x, "foo", "failing weakCompareAndSet String value"); } // Compare set and get @@ -947,9 +1003,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain String"); + assertEquals(success, true, "success weakCompareAndSetPlain String"); + String x = (String) vh.get(array, i); + assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "weakCompareAndSetPlain String value"); + assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); } { @@ -957,9 +1020,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire String"); + assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { @@ -967,9 +1037,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease String"); + assertEquals(success, true, "success weakCompareAndSetRelease String"); + String x = (String) vh.get(array, i); + assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) vh.get(array, i); - assertEquals(x, "bar", "weakCompareAndSetRelease String"); + assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); } { @@ -977,9 +1054,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet String"); + assertEquals(success, true, "success weakCompareAndSet String"); + String x = (String) vh.get(array, i); + assertEquals(x, "foo", "success weakCompareAndSet String"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "weakCompareAndSet String"); + assertEquals(x, "foo", "failing weakCompareAndSet String value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -1051,9 +1051,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain double value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain double value"); } { @@ -1061,9 +1068,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire double value"); } { @@ -1071,9 +1085,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease double"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease double"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease double value"); } { @@ -1081,9 +1102,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet double"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet double"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet double value"); } // Compare set and get @@ -1224,9 +1252,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain double value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain double value"); } { @@ -1234,9 +1269,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire double value"); } { @@ -1244,9 +1286,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease double"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease double"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease double value"); } { @@ -1254,9 +1303,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = (double) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet double"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet double"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet double value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -1051,9 +1051,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain float value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain float value"); } { @@ -1061,9 +1068,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire float value"); } { @@ -1071,9 +1085,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease float"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease float value"); } { @@ -1081,9 +1102,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet float"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet float"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet float value"); } // Compare set and get @@ -1224,9 +1252,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain float value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain float value"); } { @@ -1234,9 +1269,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire float value"); } { @@ -1244,9 +1286,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease float"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease float value"); } { @@ -1254,9 +1303,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = (float) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet float"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet float"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet float value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -1235,9 +1235,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain int value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain int value"); } { @@ -1245,9 +1252,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire int value"); } { @@ -1255,9 +1269,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease int"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease int"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease int value"); } { @@ -1265,9 +1286,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet int"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet int"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet int value"); } // Compare set and get @@ -1518,9 +1546,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain int value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain int value"); } { @@ -1528,9 +1563,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire int value"); } { @@ -1538,9 +1580,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease int"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease int"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease int value"); } { @@ -1548,9 +1597,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = (int) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet int"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet int"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet int value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -1235,9 +1235,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain long value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain long value"); } { @@ -1245,9 +1252,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire long value"); } { @@ -1255,9 +1269,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease long"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease long"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease long value"); } { @@ -1265,9 +1286,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet long"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet long"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet long value"); } // Compare set and get @@ -1518,9 +1546,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain long value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain long value"); } { @@ -1528,9 +1563,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire long value"); } { @@ -1538,9 +1580,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease long"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease long"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease long value"); } { @@ -1548,9 +1597,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = (long) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet long"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet long"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet long value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, true, false); + assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, true, "weakCompareAndSet boolean"); + assertEquals(x, true, "success weakCompareAndSet boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, true, "failing weakCompareAndSet boolean value"); } // Compare set and get @@ -446,9 +474,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -456,9 +491,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -466,9 +508,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(true, false); + assertEquals(success, false, "failing weakCompareAndSetRelease boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, false, "failing weakCompareAndSetRelease boolean value"); } { @@ -476,9 +525,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, true, "success weakCompareAndSet boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, true, "weakCompareAndSet boolean"); + assertEquals(x, true, "failing weakCompareAndSetRe boolean value"); } // Compare set and get @@ -705,9 +761,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, true, false); } - assertEquals(success, true, "weakCompareAndSetPlain boolean"); + assertEquals(success, true, "success weakCompareAndSetPlain boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, false, "success weakCompareAndSetPlain boolean value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, true, false); + assertEquals(success, false, "failing weakCompareAndSetPlain boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "weakCompareAndSetPlain boolean value"); + assertEquals(x, false, "failing weakCompareAndSetPlain boolean value"); } { @@ -715,9 +778,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, false, true); } - assertEquals(success, true, "weakCompareAndSetAcquire boolean"); + assertEquals(success, true, "success weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "weakCompareAndSetAcquire boolean"); + assertEquals(x, true, "success weakCompareAndSetAcquire boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, false, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, true, "failing weakCompareAndSetAcquire boolean value"); } { @@ -725,9 +795,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, true, false); } - assertEquals(success, true, "weakCompareAndSetRelease boolean"); + assertEquals(success, true, "success weakCompareAndSetRelease boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, false, "success weakCompareAndSetRelease boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, true, false); + assertEquals(success, false, "failing weakCompareAndSetAcquire boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, false, "weakCompareAndSetRelease boolean"); + assertEquals(x, false, "failing weakCompareAndSetAcquire boolean value"); } { @@ -735,9 +812,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, false, true); } - assertEquals(success, true, "weakCompareAndSet boolean"); + assertEquals(success, true, "success weakCompareAndSet boolean"); + boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, true, "success weakCompareAndSet boolean"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, false, false); + assertEquals(success, false, "failing weakCompareAndSet boolean"); boolean x = (boolean) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, true, "weakCompareAndSet boolean"); + assertEquals(x, true, "failing weakCompareAndSet boolean value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte"); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); } // Compare set and get @@ -468,9 +496,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -478,9 +513,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -488,9 +530,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetRelease byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetRelease byte value"); } { @@ -498,9 +547,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetRe byte value"); } // Compare set and get @@ -749,9 +805,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetPlain byte"); + assertEquals(success, true, "success weakCompareAndSetPlain byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (byte)0x23, "success weakCompareAndSetPlain byte value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetPlain byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "weakCompareAndSetPlain byte value"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetPlain byte value"); } { @@ -759,9 +822,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSetAcquire byte"); + assertEquals(success, true, "success weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "weakCompareAndSetAcquire byte"); + assertEquals(x, (byte)0x01, "success weakCompareAndSetAcquire byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (byte)0x01, "failing weakCompareAndSetAcquire byte value"); } { @@ -769,9 +839,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, (byte)0x01, (byte)0x23); } - assertEquals(success, true, "weakCompareAndSetRelease byte"); + assertEquals(success, true, "success weakCompareAndSetRelease byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (byte)0x23, "success weakCompareAndSetRelease byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (byte)0x01, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSetAcquire byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x23, "weakCompareAndSetRelease byte"); + assertEquals(x, (byte)0x23, "failing weakCompareAndSetAcquire byte value"); } { @@ -779,9 +856,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (byte)0x23, (byte)0x01); } - assertEquals(success, true, "weakCompareAndSet byte"); + assertEquals(success, true, "success weakCompareAndSet byte"); + byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (byte)0x01, "success weakCompareAndSet byte"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (byte)0x23, (byte)0x45); + assertEquals(success, false, "failing weakCompareAndSet byte"); byte x = (byte) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (byte)0x01, "weakCompareAndSet byte"); + assertEquals(x, (byte)0x01, "failing weakCompareAndSet byte value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, '\u0123', "weakCompareAndSet char"); + assertEquals(x, '\u0123', "success weakCompareAndSet char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); } // Compare set and get @@ -468,9 +496,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact('\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact('\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -478,9 +513,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact('\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact('\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -488,9 +530,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact('\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact('\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetRelease char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, '\u4567', "failing weakCompareAndSetRelease char value"); } { @@ -498,9 +547,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact('\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, '\u0123', "success weakCompareAndSet char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact('\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, '\u0123', "weakCompareAndSet char"); + assertEquals(x, '\u0123', "failing weakCompareAndSetRe char value"); } // Compare set and get @@ -749,9 +805,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetPlain char"); + assertEquals(success, true, "success weakCompareAndSetPlain char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, '\u4567', "success weakCompareAndSetPlain char value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetPlain char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "weakCompareAndSetPlain char value"); + assertEquals(x, '\u4567', "failing weakCompareAndSetPlain char value"); } { @@ -759,9 +822,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSetAcquire char"); + assertEquals(success, true, "success weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "weakCompareAndSetAcquire char"); + assertEquals(x, '\u0123', "success weakCompareAndSetAcquire char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, '\u0123', "failing weakCompareAndSetAcquire char value"); } { @@ -769,9 +839,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, '\u0123', '\u4567'); } - assertEquals(success, true, "weakCompareAndSetRelease char"); + assertEquals(success, true, "success weakCompareAndSetRelease char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, '\u4567', "success weakCompareAndSetRelease char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, '\u0123', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSetAcquire char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u4567', "weakCompareAndSetRelease char"); + assertEquals(x, '\u4567', "failing weakCompareAndSetAcquire char value"); } { @@ -779,9 +856,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, '\u4567', '\u0123'); } - assertEquals(success, true, "weakCompareAndSet char"); + assertEquals(success, true, "success weakCompareAndSet char"); + char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, '\u0123', "success weakCompareAndSet char"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, '\u4567', '\u89AB'); + assertEquals(success, false, "failing weakCompareAndSet char"); char x = (char) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, '\u0123', "weakCompareAndSet char"); + assertEquals(x, '\u0123', "failing weakCompareAndSet char value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0d, "weakCompareAndSet double"); + assertEquals(x, 1.0d, "success weakCompareAndSet double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); } // Compare set and get @@ -390,9 +418,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -400,9 +435,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -410,9 +452,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetRelease double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 2.0d, "failing weakCompareAndSetRelease double value"); } { @@ -420,9 +469,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 1.0d, "success weakCompareAndSet double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0d, "weakCompareAndSet double"); + assertEquals(x, 1.0d, "failing weakCompareAndSetRe double value"); } // Compare set and get @@ -593,9 +649,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetPlain double"); + assertEquals(success, true, "success weakCompareAndSetPlain double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 2.0d, "success weakCompareAndSetPlain double value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetPlain double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "weakCompareAndSetPlain double value"); + assertEquals(x, 2.0d, "failing weakCompareAndSetPlain double value"); } { @@ -603,9 +666,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSetAcquire double"); + assertEquals(success, true, "success weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "weakCompareAndSetAcquire double"); + assertEquals(x, 1.0d, "success weakCompareAndSetAcquire double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 1.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -613,9 +683,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0d, 2.0d); } - assertEquals(success, true, "weakCompareAndSetRelease double"); + assertEquals(success, true, "success weakCompareAndSetRelease double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 2.0d, "success weakCompareAndSetRelease double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 1.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSetAcquire double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0d, "weakCompareAndSetRelease double"); + assertEquals(x, 2.0d, "failing weakCompareAndSetAcquire double value"); } { @@ -623,9 +700,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0d, 1.0d); } - assertEquals(success, true, "weakCompareAndSet double"); + assertEquals(success, true, "success weakCompareAndSet double"); + double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 1.0d, "success weakCompareAndSet double"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0d, 3.0d); + assertEquals(success, false, "failing weakCompareAndSet double"); double x = (double) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0d, "weakCompareAndSet double"); + assertEquals(x, 1.0d, "failing weakCompareAndSet double value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1.0f, "weakCompareAndSet float"); + assertEquals(x, 1.0f, "success weakCompareAndSet float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); } // Compare set and get @@ -390,9 +418,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -400,9 +435,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -410,9 +452,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetRelease float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 2.0f, "failing weakCompareAndSetRelease float value"); } { @@ -420,9 +469,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 1.0f, "success weakCompareAndSet float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1.0f, "weakCompareAndSet float"); + assertEquals(x, 1.0f, "failing weakCompareAndSetRe float value"); } // Compare set and get @@ -593,9 +649,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetPlain float"); + assertEquals(success, true, "success weakCompareAndSetPlain float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 2.0f, "success weakCompareAndSetPlain float value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetPlain float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "weakCompareAndSetPlain float value"); + assertEquals(x, 2.0f, "failing weakCompareAndSetPlain float value"); } { @@ -603,9 +666,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSetAcquire float"); + assertEquals(success, true, "success weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "weakCompareAndSetAcquire float"); + assertEquals(x, 1.0f, "success weakCompareAndSetAcquire float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 1.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -613,9 +683,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1.0f, 2.0f); } - assertEquals(success, true, "weakCompareAndSetRelease float"); + assertEquals(success, true, "success weakCompareAndSetRelease float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 2.0f, "success weakCompareAndSetRelease float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 1.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSetAcquire float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 2.0f, "weakCompareAndSetRelease float"); + assertEquals(x, 2.0f, "failing weakCompareAndSetAcquire float value"); } { @@ -623,9 +700,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0f, 1.0f); } - assertEquals(success, true, "weakCompareAndSet float"); + assertEquals(success, true, "success weakCompareAndSet float"); + float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 1.0f, "success weakCompareAndSet float"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 2.0f, 3.0f); + assertEquals(success, false, "failing weakCompareAndSet float"); float x = (float) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1.0f, "weakCompareAndSet float"); + assertEquals(x, 1.0f, "failing weakCompareAndSet float value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x01234567, "weakCompareAndSet int"); + assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); } // Compare set and get @@ -468,9 +496,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -478,9 +513,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -488,9 +530,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetRelease int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetRelease int value"); } { @@ -498,9 +547,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x01234567, "weakCompareAndSet int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSetRe int value"); } // Compare set and get @@ -749,9 +805,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetPlain int"); + assertEquals(success, true, "success weakCompareAndSetPlain int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetPlain int value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetPlain int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetPlain int value"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetPlain int value"); } { @@ -759,9 +822,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSetAcquire int"); + assertEquals(success, true, "success weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "weakCompareAndSetAcquire int"); + assertEquals(x, 0x01234567, "success weakCompareAndSetAcquire int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0x01234567, "failing weakCompareAndSetAcquire int value"); } { @@ -769,9 +839,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 0x01234567, 0x89ABCDEF); } - assertEquals(success, true, "weakCompareAndSetRelease int"); + assertEquals(success, true, "success weakCompareAndSetRelease int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0x89ABCDEF, "success weakCompareAndSetRelease int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x01234567, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x89ABCDEF, "weakCompareAndSetRelease int"); + assertEquals(x, 0x89ABCDEF, "failing weakCompareAndSetAcquire int value"); } { @@ -779,9 +856,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0x89ABCDEF, 0x01234567); } - assertEquals(success, true, "weakCompareAndSet int"); + assertEquals(success, true, "success weakCompareAndSet int"); + int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0x01234567, "success weakCompareAndSet int"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0x89ABCDEF, 0xCAFEBABE); + assertEquals(success, false, "failing weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x01234567, "weakCompareAndSet int"); + assertEquals(x, 0x01234567, "failing weakCompareAndSet int value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long"); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); } // Compare set and get @@ -468,9 +496,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -478,9 +513,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -488,9 +530,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetRelease long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetRelease long value"); } { @@ -498,9 +547,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetRe long value"); } // Compare set and get @@ -749,9 +805,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetPlain long"); + assertEquals(success, true, "success weakCompareAndSetPlain long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetPlain long value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetPlain long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetPlain long value"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetPlain long value"); } { @@ -759,9 +822,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSetAcquire long"); + assertEquals(success, true, "success weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSetAcquire long"); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSetAcquire long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSetAcquire long value"); } { @@ -769,9 +839,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 0x0123456789ABCDEFL, 0xCAFEBABECAFEBABEL); } - assertEquals(success, true, "weakCompareAndSetRelease long"); + assertEquals(success, true, "success weakCompareAndSetRelease long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0xCAFEBABECAFEBABEL, "success weakCompareAndSetRelease long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 0x0123456789ABCDEFL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0xCAFEBABECAFEBABEL, "weakCompareAndSetRelease long"); + assertEquals(x, 0xCAFEBABECAFEBABEL, "failing weakCompareAndSetAcquire long value"); } { @@ -779,9 +856,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0x0123456789ABCDEFL); } - assertEquals(success, true, "weakCompareAndSet long"); + assertEquals(success, true, "success weakCompareAndSet long"); + long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, 0x0123456789ABCDEFL, "success weakCompareAndSet long"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 0xCAFEBABECAFEBABEL, 0xDEADBEEFDEADBEEFL); + assertEquals(success, false, "failing weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 0x0123456789ABCDEFL, "weakCompareAndSet long"); + assertEquals(x, 0x0123456789ABCDEFL, "failing weakCompareAndSet long value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, (short)0x0123, "weakCompareAndSet short"); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); } // Compare set and get @@ -468,9 +496,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact((short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -478,9 +513,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact((short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -488,9 +530,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact((short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetRelease short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetRelease short value"); } { @@ -498,9 +547,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact((short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, (short)0x0123, "weakCompareAndSet short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetRe short value"); } // Compare set and get @@ -749,9 +805,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetPlain short"); + assertEquals(success, true, "success weakCompareAndSetPlain short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (short)0x4567, "success weakCompareAndSetPlain short value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetPlain short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "weakCompareAndSetPlain short value"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetPlain short value"); } { @@ -759,9 +822,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSetAcquire short"); + assertEquals(success, true, "success weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "weakCompareAndSetAcquire short"); + assertEquals(x, (short)0x0123, "success weakCompareAndSetAcquire short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (short)0x0123, "failing weakCompareAndSetAcquire short value"); } { @@ -769,9 +839,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, (short)0x0123, (short)0x4567); } - assertEquals(success, true, "weakCompareAndSetRelease short"); + assertEquals(success, true, "success weakCompareAndSetRelease short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (short)0x4567, "success weakCompareAndSetRelease short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, (short)0x0123, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSetAcquire short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x4567, "weakCompareAndSetRelease short"); + assertEquals(x, (short)0x4567, "failing weakCompareAndSetAcquire short value"); } { @@ -779,9 +856,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (short)0x4567, (short)0x0123); } - assertEquals(success, true, "weakCompareAndSet short"); + assertEquals(success, true, "success weakCompareAndSet short"); + short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, (short)0x0123, "success weakCompareAndSet short"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, (short)0x4567, (short)0x89AB); + assertEquals(success, false, "failing weakCompareAndSet short"); short x = (short) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, (short)0x0123, "weakCompareAndSet short"); + assertEquals(x, (short)0x0123, "failing weakCompareAndSet short value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -212,9 +212,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain String"); + assertEquals(success, true, "success weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "weakCompareAndSetPlain String value"); + assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); } { @@ -222,9 +229,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire String"); + assertEquals(success, true, "success weakCompareAndSetAcquire String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { @@ -232,9 +246,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease String"); + assertEquals(success, true, "success weakCompareAndSetRelease String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "bar", "weakCompareAndSetRelease String"); + assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); } { @@ -242,9 +263,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet String"); + assertEquals(success, true, "success weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "weakCompareAndSet String"); + assertEquals(x, "foo", "success weakCompareAndSet String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, "foo", "failing weakCompareAndSet String value"); } // Compare set and get @@ -368,9 +396,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain String"); + assertEquals(success, true, "success weakCompareAndSetPlain String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact("foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "weakCompareAndSetPlain String value"); + assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); } { @@ -378,9 +413,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire String"); + assertEquals(success, true, "success weakCompareAndSetAcquire String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { @@ -388,9 +430,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease String"); + assertEquals(success, true, "success weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "bar", "weakCompareAndSetRelease String"); + assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetRelease String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, "bar", "failing weakCompareAndSetRelease String value"); } { @@ -398,9 +447,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet String"); + assertEquals(success, true, "success weakCompareAndSet String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, "foo", "success weakCompareAndSet String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "weakCompareAndSet String"); + assertEquals(x, "foo", "failing weakCompareAndSetRe String value"); } // Compare set and get @@ -549,9 +605,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetPlain String"); + assertEquals(success, true, "success weakCompareAndSetPlain String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, "bar", "success weakCompareAndSetPlain String value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetPlain String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "weakCompareAndSetPlain String value"); + assertEquals(x, "bar", "failing weakCompareAndSetPlain String value"); } { @@ -559,9 +622,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSetAcquire String"); + assertEquals(success, true, "success weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "weakCompareAndSetAcquire String"); + assertEquals(x, "foo", "success weakCompareAndSetAcquire String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, "foo", "failing weakCompareAndSetAcquire String value"); } { @@ -569,9 +639,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar"); } - assertEquals(success, true, "weakCompareAndSetRelease String"); + assertEquals(success, true, "success weakCompareAndSetRelease String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, "bar", "success weakCompareAndSetRelease String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "foo", "baz"); + assertEquals(success, false, "failing weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "bar", "weakCompareAndSetRelease String"); + assertEquals(x, "bar", "failing weakCompareAndSetAcquire String value"); } { @@ -579,9 +656,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "foo"); } - assertEquals(success, true, "weakCompareAndSet String"); + assertEquals(success, true, "success weakCompareAndSet String"); + String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, "foo", "success weakCompareAndSet String"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "bar", "baz"); + assertEquals(success, false, "failing weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "weakCompareAndSet String"); + assertEquals(x, "foo", "failing weakCompareAndSet String value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -659,9 +659,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(recv, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(recv, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -669,9 +676,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(recv, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -679,9 +693,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = vh.weakCompareAndSetRelease(recv, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); } { @@ -689,9 +710,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(recv, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(recv); - assertEquals(x, $value1$, "weakCompareAndSet $type$ value"); + assertEquals(x, $value1$, "success weakCompareAndSet $type$ value"); + } + + { + boolean success = vh.weakCompareAndSet(recv, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -1036,9 +1064,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain($value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = vh.weakCompareAndSetPlain($value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1046,9 +1081,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire($value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = vh.weakCompareAndSetAcquire($value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1056,9 +1098,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease($value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = vh.weakCompareAndSetRelease($value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1066,9 +1115,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet($value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(); + assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + } + + { + boolean success = vh.weakCompareAndSet($value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "weakCompareAndSet $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -1416,9 +1472,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1426,9 +1489,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1436,9 +1506,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1446,9 +1523,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "weakCompareAndSet $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -1592,9 +1592,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1602,9 +1609,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1612,9 +1626,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1622,9 +1643,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet $type$"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet $type$"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -1881,9 +1909,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, VALUE_2, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = vh.weakCompareAndSetPlain(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetPlain $type$ value"); } { @@ -1891,9 +1926,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); + assertEquals(x, VALUE_1, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -1901,9 +1943,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); + assertEquals(x, VALUE_2, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_2, "failing weakCompareAndSetRelease $type$ value"); } { @@ -1911,9 +1960,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_1); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = ($type$) vh.get(array, i); + assertEquals(x, VALUE_1, "success weakCompareAndSet $type$"); + } + + { + boolean success = vh.weakCompareAndSet(array, i, VALUE_2, VALUE_3); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, VALUE_1, "weakCompareAndSet $type$"); + assertEquals(x, VALUE_1, "failing weakCompareAndSet $type$ value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, 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 @@ -213,9 +213,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(recv, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -223,9 +230,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -233,9 +247,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); } { @@ -243,9 +264,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "weakCompareAndSet $type$"); + assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); + assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); } // Compare set and get @@ -508,9 +536,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact($value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact($value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -518,9 +553,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -528,9 +570,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, $value2$, "failing weakCompareAndSetRelease $type$ value"); } { @@ -538,9 +587,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); + assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "weakCompareAndSet $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSetRe $type$ value"); } // Compare set and get @@ -828,9 +884,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetPlain $type$"); + assertEquals(success, true, "success weakCompareAndSetPlain $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, $value2$, "success weakCompareAndSetPlain $type$ value"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_PLAIN).invokeExact(array, i, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetPlain $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "weakCompareAndSetPlain $type$ value"); + assertEquals(x, $value2$, "failing weakCompareAndSetPlain $type$ value"); } { @@ -838,9 +901,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSetAcquire $type$"); + assertEquals(success, true, "success weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); + assertEquals(x, $value1$, "success weakCompareAndSetAcquire $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, $value1$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -848,9 +918,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, $value1$, $value2$); } - assertEquals(success, true, "weakCompareAndSetRelease $type$"); + assertEquals(success, true, "success weakCompareAndSetRelease $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, $value2$, "success weakCompareAndSetRelease $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value1$, $value3$); + assertEquals(success, false, "failing weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); + assertEquals(x, $value2$, "failing weakCompareAndSetAcquire $type$ value"); } { @@ -858,9 +935,16 @@ for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value2$, $value1$); } - assertEquals(success, true, "weakCompareAndSet $type$"); + assertEquals(success, true, "success weakCompareAndSet $type$"); + $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); + assertEquals(x, $value1$, "success weakCompareAndSet $type$"); + } + + { + boolean success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value2$, $value3$); + assertEquals(success, false, "failing weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "weakCompareAndSet $type$"); + assertEquals(x, $value1$, "failing weakCompareAndSet $type$ value"); } // Compare set and get diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/Runtime/shutdown/ShutdownInterruptedMain.java openjdk-lts-11.0.21+9/test/jdk/java/lang/Runtime/shutdown/ShutdownInterruptedMain.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/Runtime/shutdown/ShutdownInterruptedMain.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/Runtime/shutdown/ShutdownInterruptedMain.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -31,14 +31,14 @@ */ import jdk.test.lib.process.OutputAnalyzer; -import static jdk.test.lib.process.ProcessTools.createJavaProcessBuilder; +import static jdk.test.lib.process.ProcessTools.createTestJvm; import static jdk.test.lib.process.ProcessTools.executeProcess; public class ShutdownInterruptedMain { public static void main(String[] args) throws Exception { if (args.length > 0) { - ProcessBuilder pb = createJavaProcessBuilder(true, "ShutdownInterruptedMain"); + ProcessBuilder pb = createTestJvm("ShutdownInterruptedMain"); OutputAnalyzer output = executeProcess(pb); output.shouldContain("Shutdown Hook"); output.shouldHaveExitValue(0); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/StackWalker/CallerFromMain.java openjdk-lts-11.0.21+9/test/jdk/java/lang/StackWalker/CallerFromMain.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/StackWalker/CallerFromMain.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/StackWalker/CallerFromMain.java 2023-10-06 05:33:33.000000000 +0000 @@ -37,7 +37,7 @@ private static final StackWalker sw = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); public static void main(String[] args) throws Exception { if (args.length > 0) { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "CallerFromMain"); + ProcessBuilder pb = ProcessTools.createTestJvm("CallerFromMain"); OutputAnalyzer output = ProcessTools.executeProcess(pb); System.out.println(output.getOutput()); output.shouldHaveExitValue(0); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/StringBuilder/HugeCapacity.java openjdk-lts-11.0.21+9/test/jdk/java/lang/StringBuilder/HugeCapacity.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/StringBuilder/HugeCapacity.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/StringBuilder/HugeCapacity.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,25 +27,32 @@ * @summary Capacity should not get close to Integer.MAX_VALUE unless * necessary * @requires (sun.arch.data.model == "64" & os.maxMemory >= 6G) - * @run main/othervm -Xmx5G HugeCapacity + * @run main/othervm -Xms5G -Xmx5G -XX:+CompactStrings HugeCapacity true + * @run main/othervm -Xms5G -Xmx5G -XX:-CompactStrings HugeCapacity false */ public class HugeCapacity { private static int failures = 0; public static void main(String[] args) { - testLatin1(); + if (args.length == 0) { + throw new IllegalArgumentException("Need the argument"); + } + boolean isCompact = Boolean.parseBoolean(args[0]); + + testLatin1(isCompact); testUtf16(); if (failures > 0) { throw new RuntimeException(failures + " tests failed"); } } - private static void testLatin1() { + private static void testLatin1(boolean isCompact) { try { + int divisor = isCompact ? 2 : 4; StringBuilder sb = new StringBuilder(); - sb.ensureCapacity(Integer.MAX_VALUE / 2); - sb.ensureCapacity(Integer.MAX_VALUE / 2 + 1); + sb.ensureCapacity(Integer.MAX_VALUE / divisor); + sb.ensureCapacity(Integer.MAX_VALUE / divisor + 1); } catch (OutOfMemoryError oom) { oom.printStackTrace(); failures++; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/lang/System/MacEncoding/MacJNUEncoding.java openjdk-lts-11.0.21+9/test/jdk/java/lang/System/MacEncoding/MacJNUEncoding.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/lang/System/MacEncoding/MacJNUEncoding.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/lang/System/MacEncoding/MacJNUEncoding.java 2023-10-06 05:33:33.000000000 +0000 @@ -49,7 +49,7 @@ final String locale = args[2]; System.out.println("Running test for locale: " + locale); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( ExpectedEncoding.class.getName(), args[0], args[1]); Map env = pb.environment(); env.put("LANG", locale); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/DivisionOverflow.java openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/DivisionOverflow.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/DivisionOverflow.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/DivisionOverflow.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8022780 - * @summary Test division of large values - * @run main/othervm -Xshare:off DivisionOverflow - * @author Dmitry Nadezhin - */ -import java.math.BigInteger; - -public class DivisionOverflow { - - public static void main(String[] args) { - try { - BigInteger a = BigInteger.ONE.shiftLeft(2147483646); - BigInteger b = BigInteger.ONE.shiftLeft(1568); - BigInteger[] qr = a.divideAndRemainder(b); - BigInteger q = qr[0]; - BigInteger r = qr[1]; - if (!r.equals(BigInteger.ZERO)) { - throw new RuntimeException("Incorrect signum() of remainder " + r.signum()); - } - if (q.bitLength() != 2147482079) { - throw new RuntimeException("Incorrect bitLength() of quotient " + q.bitLength()); - } - System.out.println("Division of large values passed without overflow."); - } catch (OutOfMemoryError e) { - // possible - System.err.println("DivisionOverflow skipped: OutOfMemoryError"); - System.err.println("Run jtreg with -javaoption:-Xmx8g"); - } - } -} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/largeMemory/DivisionOverflow.java openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/largeMemory/DivisionOverflow.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/largeMemory/DivisionOverflow.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/largeMemory/DivisionOverflow.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, 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 8022780 + * @summary Test division of large values + * @requires (sun.arch.data.model == "64" & os.maxMemory > 8g) + * @run main/othervm -Xshare:off -Xmx8g DivisionOverflow + * @author Dmitry Nadezhin + */ +import java.math.BigInteger; + +public class DivisionOverflow { + + public static void main(String[] args) { + try { + BigInteger a = BigInteger.ONE.shiftLeft(2147483646); + BigInteger b = BigInteger.ONE.shiftLeft(1568); + BigInteger[] qr = a.divideAndRemainder(b); + BigInteger q = qr[0]; + BigInteger r = qr[1]; + if (!r.equals(BigInteger.ZERO)) { + throw new RuntimeException("Incorrect signum() of remainder " + r.signum()); + } + if (q.bitLength() != 2147482079) { + throw new RuntimeException("Incorrect bitLength() of quotient " + q.bitLength()); + } + System.out.println("Division of large values passed without overflow."); + } catch (OutOfMemoryError e) { + // possible + System.err.println("DivisionOverflow skipped: OutOfMemoryError"); + System.err.println("Run jtreg with -javaoption:-Xmx8g"); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/largeMemory/StringConstructorOverflow.java openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/largeMemory/StringConstructorOverflow.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/largeMemory/StringConstructorOverflow.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/largeMemory/StringConstructorOverflow.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, 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 8021204 + * @summary Test constructor BigInteger(String val, int radix) on very long string + * @requires (sun.arch.data.model == "64" & os.maxMemory > 8g) + * @run main/othervm -Xshare:off -Xmx8g StringConstructorOverflow + * @author Dmitry Nadezhin + */ +import java.math.BigInteger; + +public class StringConstructorOverflow { + + // String with hexadecimal value pow(2,pow(2,34))+1 + private static String makeLongHexString() { + StringBuilder sb = new StringBuilder(); + sb.append('1'); + for (int i = 0; i < (1 << 30) - 1; i++) { + sb.append('0'); + } + sb.append('1'); + return sb.toString(); + } + + public static void main(String[] args) { + try { + BigInteger bi = new BigInteger(makeLongHexString(), 16); + if (bi.compareTo(BigInteger.ONE) <= 0) { + throw new RuntimeException("Incorrect result " + bi.toString()); + } + } catch (ArithmeticException e) { + // expected + System.out.println("Overflow is reported by ArithmeticException, as expected"); + } catch (OutOfMemoryError e) { + // possible + System.err.println("StringConstructorOverflow skipped: OutOfMemoryError"); + System.err.println("Run jtreg with -javaoption:-Xmx8g"); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/largeMemory/SymmetricRangeTests.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,665 @@ +/* + * 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. + */ + +/* + * @test + * @bug 6910473 8021204 8021203 9005933 8074460 8078672 + * @summary Test range of BigInteger values (use -Dseed=X to set PRNG seed) + * @library /test/lib + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 10g) + * @run main/timeout=180/othervm -Xmx8g -XX:+CompactStrings SymmetricRangeTests + * @author Dmitry Nadezhin + * @key randomness + */ +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Arrays; +import java.math.BigInteger; +import java.util.Random; +import jdk.test.lib.RandomFactory; + +public class SymmetricRangeTests { + + private static final BigInteger MAX_VALUE = makeMaxValue(); + private static final BigInteger MIN_VALUE = MAX_VALUE.negate(); + + private static BigInteger makeMaxValue() { + byte[] ba = new byte[1 << 28]; + Arrays.fill(ba, (byte) 0xFF); + ba[0] = (byte) 0x7F; + return new BigInteger(ba); + } + + private static void check(String msg, BigInteger actual, BigInteger expected) { + if (!actual.equals(expected)) { + throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength()); + } + } + + private static void check(String msg, double actual, double expected) { + if (actual != expected) { + throw new RuntimeException(msg + "=" + actual); + } + } + + private static void check(String msg, float actual, float expected) { + if (actual != expected) { + throw new RuntimeException(msg + "=" + actual); + } + } + + private static void check(String msg, long actual, long expected) { + if (actual != expected) { + throw new RuntimeException(msg + "=" + actual); + } + } + + private static void check(String msg, int actual, int expected) { + if (actual != expected) { + throw new RuntimeException(msg + "=" + actual); + } + } + + private static void testOverflowInMakePositive() { + System.out.println("Testing overflow in BigInteger.makePositive"); + byte[] ba = new byte[Integer.MAX_VALUE - 2]; + ba[0] = (byte) 0x80; + try { + BigInteger actual = new BigInteger(ba); + throw new RuntimeException("new BigInteger(ba).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testBug8021204() { + System.out.println("Testing Bug 8021204"); + StringBuilder sb = new StringBuilder(); + sb.append('1'); + for (int i = 0; i < (1 << 30) - 1; i++) { + sb.append('0'); + } + sb.append('1'); + String s = sb.toString(); + sb = null; + try { + BigInteger actual = new BigInteger(s, 16); + throw new RuntimeException("new BigInteger(\"1000...001\").bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testOverflowInBitSieve() { + System.out.println("Testing overflow in BitSieve.sieveSingle"); + int bitLength = (5 << 27) - 1; + try { + Random random = RandomFactory.getRandom(); + BigInteger actual = new BigInteger(bitLength, 0, random); + throw new RuntimeException("new BigInteger(bitLength, 0, null).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger bi = BigInteger.ONE.shiftLeft(bitLength - 1).subtract(BigInteger.ONE); + BigInteger actual = bi.nextProbablePrime(); + throw new RuntimeException("bi.nextActualPrime().bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testAdd() { + System.out.println("Testing BigInteger.add"); + try { + BigInteger actual = MAX_VALUE.add(BigInteger.ONE); + throw new RuntimeException("BigInteger.MAX_VALUE.add(BigInteger.ONE).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testSubtract() { + System.out.println("Testing BigInteger.subtract"); + try { + BigInteger actual = MIN_VALUE.subtract(BigInteger.ONE); + throw new RuntimeException("BigInteger.MIN_VALUE.subtract(BigInteger.ONE).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testMultiply() { + System.out.println("Testing BigInteger.multiply"); + int py = 2000; + int px = Integer.MAX_VALUE - py; + BigInteger x = BigInteger.ONE.shiftLeft(px); + BigInteger y = BigInteger.ONE.shiftLeft(py); + try { + BigInteger actual = x.multiply(y); + throw new RuntimeException("(1 << " + px + " ) * (1 << " + py + ").bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testDivide() { + System.out.println("Testing BigInteger.divide"); + check("BigInteger.MIN_VALUE.divide(BigInteger.valueOf(-1))", + MIN_VALUE.divide(BigInteger.valueOf(-1)), MAX_VALUE); + check("BigInteger.MIN_VALUE.divide(BigInteger.ONE)", + MIN_VALUE.divide(BigInteger.ONE), MIN_VALUE); + } + + private static void testDivideAndRemainder(String msg, BigInteger dividend, BigInteger divisor, + BigInteger expectedQuotent, BigInteger expectedRemainder) { + BigInteger[] qr = dividend.divideAndRemainder(divisor); + check(msg + "[0]", qr[0], expectedQuotent); + check(msg + "[1]", qr[1], expectedRemainder); + } + + private static void testDivideAndRemainder() { + System.out.println("Testing BigInteger.divideAndRemainder"); + testDivideAndRemainder("BigInteger.MIN_VALUE.divideAndRemainder(BigInteger.valueOf(-1))", + MIN_VALUE, BigInteger.valueOf(-1), + MAX_VALUE, + BigInteger.ZERO); + } + + private static void testBug9005933() { + System.out.println("Testing Bug 9005933"); + int dividendPow = 2147483646; + int divisorPow = 1568; + BigInteger dividend = BigInteger.ONE.shiftLeft(dividendPow); + BigInteger divisor = BigInteger.ONE.shiftLeft(divisorPow); + testDivideAndRemainder("(1 << " + dividendPow + ").divideAndRemainder(1 << " + divisorPow + ")", + dividend, divisor, + BigInteger.ONE.shiftLeft(dividendPow - divisorPow), + BigInteger.ZERO); + } + + private static void testRemainder() { + System.out.println("Testing BigInteger.remainder"); + check("BigInteger.MIN_VALUE.remainder(BigInteger.valueOf(-1))", + MIN_VALUE.remainder(BigInteger.valueOf(-1)), BigInteger.ZERO); + } + + private static void testPow() { + System.out.println("Testing BigInteger.pow"); + check("BigInteger.MIN_VALUE.pow(1)", + MIN_VALUE.pow(1), MIN_VALUE); + try { + BigInteger actual = BigInteger.valueOf(4).pow(Integer.MAX_VALUE); + throw new RuntimeException("BigInteger.valueOf(4).pow(Integer.MAX_VALUE).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testGcd() { + System.out.println("Testing BigInteger.gcd"); + check("BigInteger.MIN_VALUE.gcd(BigInteger.MIN_VALUE)", + MIN_VALUE.gcd(MIN_VALUE), MAX_VALUE); + check("BigInteger.MIN_VALUE.gcd(BigInteger.ZERO)", + MIN_VALUE.gcd(BigInteger.ZERO), MAX_VALUE); + check("BigInteger.ZERO.gcd(MIN_VALUE)", + BigInteger.ZERO.gcd(MIN_VALUE), MAX_VALUE); + } + + private static void testAbs() { + System.out.println("Testing BigInteger.abs"); + check("BigInteger.MIN_VALUE.abs()", + MIN_VALUE.abs(), MAX_VALUE); + check("BigInteger.MAX_VALUE.abs()", + MAX_VALUE.abs(), MAX_VALUE); + } + + private static void testNegate() { + System.out.println("Testing BigInteger.negate"); + check("BigInteger.MIN_VALUE.negate()", + MIN_VALUE.negate(), MAX_VALUE); + check("BigInteger.MAX_VALUE.negate()", + MAX_VALUE.negate(), MIN_VALUE); + } + + private static void testMod() { + System.out.println("Testing BigInteger.mod"); + check("BigInteger.MIN_VALUE.mod(BigInteger.MAX_VALUE)", + MIN_VALUE.mod(MAX_VALUE), BigInteger.ZERO); + check("BigInteger.MAX_VALUE.mod(BigInteger.MAX_VALUE)", + MIN_VALUE.mod(MAX_VALUE), BigInteger.ZERO); + } + + private static void testModPow() { + System.out.println("Testing BigInteger.modPow"); + BigInteger x = BigInteger.valueOf(3); + BigInteger m = BigInteger.valueOf(-4).subtract(MIN_VALUE); + check("BigInteger.valueOf(3).modPow(BigInteger.ONE, m)", + x.modPow(BigInteger.ONE, m), x); + } + + // slow test + private static void testModInverse() { + System.out.println("Testing BigInteger.modInverse"); + check("BigInteger.MIN_VALUE.modInverse(BigInteger.MAX_VALUE)", + MIN_VALUE.modInverse(MAX_VALUE), MAX_VALUE.subtract(BigInteger.ONE)); + } + + private static void testShiftLeft() { + System.out.println("Testing BigInteger.shiftLeft"); + try { + BigInteger actual = MIN_VALUE.shiftLeft(1); + throw new RuntimeException("BigInteger.MIN_VALUE.shiftLeft(1).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger actual = MAX_VALUE.shiftLeft(1); + throw new RuntimeException("BigInteger.MAX_VALUE.shiftLeft(1).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testShiftRight() { + System.out.println("Testing BigInteger.shiftRight"); + try { + BigInteger actual = MIN_VALUE.shiftRight(-1); + throw new RuntimeException("BigInteger.MIN_VALUE.shiftRight(-1).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger actual = MAX_VALUE.shiftRight(-1); + throw new RuntimeException("BigInteger.MAX_VALUE.shiftRight(-1).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testAnd() { + System.out.println("Testing BigInteger.and"); + check("BigInteger.MIN_VALUE.and(BigInteger.MIN_VALUE)", + MIN_VALUE.and(MIN_VALUE), MIN_VALUE); + check("BigInteger.MAX_VALUE.and(BigInteger.MAX_VALUE)", + MAX_VALUE.and(MAX_VALUE), MAX_VALUE); + check("BigInteger.MIN_VALUE.and(BigInteger.MAX_VALUE)", + MIN_VALUE.and(MAX_VALUE), BigInteger.ONE); + try { + BigInteger actual = MIN_VALUE.and(BigInteger.valueOf(-2)); + throw new RuntimeException("BigInteger.MIN_VALUE.and(-2)).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testOr() { + System.out.println("Testing BigInteger.or"); + check("BigInteger.MIN_VALUE.or(BigInteger.MIN_VALUE)", + MIN_VALUE.or(MIN_VALUE), MIN_VALUE); + check("BigInteger.MAX_VALUE.or(BigInteger.MAX_VALUE)", + MAX_VALUE.or(MAX_VALUE), MAX_VALUE); + check("BigInteger.MIN_VALUE.and(BigInteger.MAX_VALUE)", + MIN_VALUE.or(MAX_VALUE), BigInteger.valueOf(-1)); + } + + private static void testXor() { + System.out.println("Testing BigInteger.xor"); + check("BigInteger.MIN_VALUE.xor(BigInteger.MIN_VALUE)", + MIN_VALUE.xor(MIN_VALUE), BigInteger.ZERO); + check("BigInteger.MAX_VALUE.xor(BigInteger.MAX_VALUE)", + MAX_VALUE.xor(MAX_VALUE), BigInteger.ZERO); + check("BigInteger.MIN_VALUE.xor(BigInteger.MAX_VALUE)", + MIN_VALUE.xor(MAX_VALUE), BigInteger.valueOf(-2)); + try { + BigInteger actual = MIN_VALUE.xor(BigInteger.ONE); + throw new RuntimeException("BigInteger.MIN_VALUE.xor(BigInteger.ONE)).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testNot() { + System.out.println("Testing BigInteger.not"); + check("BigInteger.MIN_VALUE.not()", + MIN_VALUE.not(), MAX_VALUE.subtract(BigInteger.ONE)); + try { + BigInteger actual = MAX_VALUE.not(); + throw new RuntimeException("BigInteger.MAX_VALUE.not()).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testSetBit() { + System.out.println("Testing BigInteger.setBit"); + check("BigInteger.MIN_VALUE.setBit(" + Integer.MAX_VALUE + ")", + MIN_VALUE.setBit(Integer.MAX_VALUE), MIN_VALUE); + try { + BigInteger actual = MAX_VALUE.setBit(Integer.MAX_VALUE); + throw new RuntimeException("BigInteger.MAX_VALUE.setBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testClearBit() { + System.out.println("Testing BigInteger.clearBit"); + check("BigInteger.MAX_VALUE.clearBit(" + Integer.MAX_VALUE + ")", + MAX_VALUE.clearBit(Integer.MAX_VALUE), MAX_VALUE); + try { + BigInteger actual = MIN_VALUE.clearBit(Integer.MAX_VALUE); + throw new RuntimeException("BigInteger.MIN_VALUE.clearBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger actual = MIN_VALUE.clearBit(0); + throw new RuntimeException("BigInteger.MIN_VALUE.clearBit(0).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testFlipBit() { + System.out.println("Testing BigInteger.flipBit"); + try { + BigInteger actual = MIN_VALUE.flipBit(Integer.MAX_VALUE); + throw new RuntimeException("BigInteger.MIN_VALUE.flipBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger actual = MIN_VALUE.flipBit(0); + throw new RuntimeException("BigInteger.MIN_VALUE.flipBit(0).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger actual = MAX_VALUE.flipBit(Integer.MAX_VALUE); + throw new RuntimeException("BigInteger.MAX_VALUE.flipBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testGetLowestSetBit() { + System.out.println("Testing BigInteger.getLowestSetBit"); + check("BigInteger.MIN_VALUE.getLowestSetBit()", + MIN_VALUE.getLowestSetBit(), 0); + check("BigInteger.MAX_VALUE.getLowestSetBit()", + MAX_VALUE.getLowestSetBit(), 0); + } + + private static void testBitLength() { + System.out.println("Testing BigInteger.bitLength"); + check("BigInteger.MIN_NEXT.bitLength()", + MIN_VALUE.bitLength(), Integer.MAX_VALUE); + check("BigInteger.MAX_VALUE.bitLength()", + MAX_VALUE.bitLength(), Integer.MAX_VALUE); + } + + private static void testBitCount() { + System.out.println("Testing BigInteger.bitCount"); + check("BigInteger.MIN_VALUE.bitCount()", + MIN_VALUE.bitCount(), Integer.MAX_VALUE - 1); + check("BigInteger.MAX_VALUE.bitCount()", + MAX_VALUE.bitCount(), Integer.MAX_VALUE); + } + + private static void testToString(String msg, int radix, BigInteger bi, int length, String startsWith, char c) { + String s = bi.toString(radix); + if (s.length() != length) { + throw new RuntimeException(msg + ".length=" + s.length()); + } + if (!s.startsWith(startsWith)) { + throw new RuntimeException(msg + "[0]=" + s.substring(0, startsWith.length())); + } + for (int i = startsWith.length(); i < s.length(); i++) { + if (s.charAt(i) != c) { + throw new RuntimeException(msg + "[" + i + "]='" + s.charAt(i) + "'"); + } + } + } + + private static void testToString() { + System.out.println("Testing BigInteger.toString"); + testToString("BigInteger.MIN_VALUE.toString(16)=", 16, + BigInteger.valueOf(-1).shiftLeft(Integer.MAX_VALUE - 1), + (1 << 29) + 1, "-4", '0'); + } + + private static void testToByteArrayWithConstructor(String msg, BigInteger bi, int length, byte msb, byte b, byte lsb) { + byte[] ba = bi.toByteArray(); + if (ba.length != length) { + throw new RuntimeException(msg + ".length=" + ba.length); + } + if (ba[0] != msb) { + throw new RuntimeException(msg + "[0]=" + ba[0]); + } + for (int i = 1; i < ba.length - 1; i++) { + if (ba[i] != b) { + throw new RuntimeException(msg + "[" + i + "]=" + ba[i]); + } + } + if (ba[ba.length - 1] != lsb) { + throw new RuntimeException(msg + "[" + (ba.length - 1) + "]=" + ba[ba.length - 1]); + } + BigInteger actual = new BigInteger(ba); + if (!actual.equals(bi)) { + throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength()); + } + } + + private static void testToByteArrayWithConstructor() { + System.out.println("Testing BigInteger.toByteArray with constructor"); + testToByteArrayWithConstructor("BigInteger.MIN_VALUE.toByteArray()", + MIN_VALUE, (1 << 28), (byte) 0x80, (byte) 0x00, (byte) 0x01); + testToByteArrayWithConstructor("BigInteger.MAX_VALUE.toByteArray()", + MAX_VALUE, (1 << 28), (byte) 0x7f, (byte) 0xff, (byte) 0xff); + + byte[] ba = new byte[1 << 28]; + ba[0] = (byte) 0x80; + try { + BigInteger actual = new BigInteger(-1, ba); + throw new RuntimeException("new BigInteger(-1, ba).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + try { + BigInteger actual = new BigInteger(1, ba); + throw new RuntimeException("new BigInteger(1, ba).bitLength()=" + actual.bitLength()); + } catch (ArithmeticException e) { + // expected + } + } + + private static void testIntValue() { + System.out.println("Testing BigInteger.intValue"); + check("BigInteger.MIN_VALUE.intValue()", + MIN_VALUE.intValue(), 1); + check("BigInteger.MAX_VALUE.floatValue()", + MAX_VALUE.intValue(), -1); + } + + private static void testLongValue() { + System.out.println("Testing BigInteger.longValue"); + check("BigInteger.MIN_VALUE.longValue()", + MIN_VALUE.longValue(), 1L); + check("BigInteger.MAX_VALUE.longValue()", + MAX_VALUE.longValue(), -1L); + } + + private static void testFloatValue() { + System.out.println("Testing BigInteger.floatValue, Bug 8021203"); + check("BigInteger.MIN_VALUE_.floatValue()", + MIN_VALUE.floatValue(), Float.NEGATIVE_INFINITY); + check("BigInteger.MAX_VALUE.floatValue()", + MAX_VALUE.floatValue(), Float.POSITIVE_INFINITY); + } + + private static void testDoubleValue() { + System.out.println("Testing BigInteger.doubleValue, Bug 8021203"); + check("BigInteger.MIN_VALUE.doubleValue()", + MIN_VALUE.doubleValue(), Double.NEGATIVE_INFINITY); + check("BigInteger.MAX_VALUE.doubleValue()", + MAX_VALUE.doubleValue(), Double.POSITIVE_INFINITY); + } + + private static void testSerialization(String msg, BigInteger bi) { + try { + ByteArrayOutputStream baOut = new ByteArrayOutputStream((1 << 28) + 1000); + ObjectOutputStream out = new ObjectOutputStream(baOut); + out.writeObject(bi); + out.close(); + out = null; + byte[] ba = baOut.toByteArray(); + baOut = null; + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(ba)); + BigInteger actual = (BigInteger) in.readObject(); + if (!actual.equals(bi)) { + throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength()); + } + } catch (IOException | ClassNotFoundException e) { + throw new RuntimeException(msg + " raised exception ", e); + } + } + + private static void testSerialization() { + System.out.println("Testing BigInteger serialization"); + testSerialization("BigInteger.MIN_VALUE.intValue()", + MIN_VALUE); + testSerialization("BigInteger.MAX_VALUE.floatValue()", + MAX_VALUE); + } + + private static void testLongValueExact() { + System.out.println("Testing BigInteger.longValueExact"); + try { + long actual = MIN_VALUE.longValueExact(); + throw new RuntimeException("BigInteger.MIN_VALUE.longValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + try { + long actual = MAX_VALUE.longValueExact(); + throw new RuntimeException("BigInteger.MAX_VALUE.longValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + } + + private static void testIntValueExact() { + System.out.println("Testing BigInteger.intValueExact"); + try { + long actual = MIN_VALUE.intValueExact(); + throw new RuntimeException("BigInteger.MIN_VALUE.intValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + try { + long actual = MAX_VALUE.intValueExact(); + throw new RuntimeException("BigInteger.MAX_VALUE.intValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + } + + private static void testShortValueExact() { + System.out.println("Testing BigInteger.shortValueExact"); + try { + long actual = MIN_VALUE.shortValueExact(); + throw new RuntimeException("BigInteger.MIN_VALUE.shortValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + try { + long actual = MAX_VALUE.shortValueExact(); + throw new RuntimeException("BigInteger.MAX_VALUE.shortValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + } + + private static void testByteValueExact() { + System.out.println("Testing BigInteger.byteValueExact"); + try { + long actual = MIN_VALUE.byteValueExact(); + throw new RuntimeException("BigInteger.MIN_VALUE.byteValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + try { + long actual = MAX_VALUE.byteValueExact(); + throw new RuntimeException("BigInteger.MAX_VALUE.byteValueExact()= " + actual); + } catch (ArithmeticException e) { + // excpected + } + } + + public static void main(String... args) { + testOverflowInMakePositive(); + testBug8021204(); + testOverflowInBitSieve(); + testAdd(); + testSubtract(); + testMultiply(); + testDivide(); + testDivideAndRemainder(); + testBug9005933(); + testRemainder(); + testPow(); + testGcd(); + testAbs(); + testNegate(); + testMod(); + testModPow(); +// testModInverse(); + testShiftLeft(); + testShiftRight(); + testAnd(); + testOr(); + testXor(); + testNot(); + testSetBit(); + testClearBit(); + testFlipBit(); + testGetLowestSetBit(); + testBitLength(); + testBitCount(); + testToString(); + testToByteArrayWithConstructor(); + testIntValue(); + testLongValue(); + testFloatValue(); + testDoubleValue(); + testSerialization(); + testLongValueExact(); + testIntValueExact(); + testShortValueExact(); + testByteValueExact(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/StringConstructorOverflow.java openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/StringConstructorOverflow.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/StringConstructorOverflow.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/StringConstructorOverflow.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013, 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 8021204 - * @summary Test constructor BigInteger(String val, int radix) on very long string - * @ignore This test has huge memory requirements - * @run main/othervm -Xshare:off -Xmx8g StringConstructorOverflow - * @author Dmitry Nadezhin - */ -import java.math.BigInteger; - -public class StringConstructorOverflow { - - // String with hexadecimal value pow(2,pow(2,34))+1 - private static String makeLongHexString() { - StringBuilder sb = new StringBuilder(); - sb.append('1'); - for (int i = 0; i < (1 << 30) - 1; i++) { - sb.append('0'); - } - sb.append('1'); - return sb.toString(); - } - - public static void main(String[] args) { - try { - BigInteger bi = new BigInteger(makeLongHexString(), 16); - if (bi.compareTo(BigInteger.ONE) <= 0) { - throw new RuntimeException("Incorrect result " + bi.toString()); - } - } catch (ArithmeticException e) { - // expected - System.out.println("Overflow is reported by ArithmeticException, as expected"); - } catch (OutOfMemoryError e) { - // possible - System.err.println("StringConstructorOverflow skipped: OutOfMemoryError"); - System.err.println("Run jtreg with -javaoption:-Xmx8g"); - } - } -} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/SymmetricRangeTests.java openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/SymmetricRangeTests.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/math/BigInteger/SymmetricRangeTests.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/math/BigInteger/SymmetricRangeTests.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,665 +0,0 @@ -/* - * Copyright (c) 2013, 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 - * @library /test/lib - * @ignore This test has huge memory requirements - * @run main/timeout=180/othervm -Xmx8g SymmetricRangeTests - * @bug 6910473 8021204 8021203 9005933 8074460 8078672 - * @summary Test range of BigInteger values (use -Dseed=X to set PRNG seed) - * @author Dmitry Nadezhin - * @key randomness - */ -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; -import java.math.BigInteger; -import java.util.Random; -import jdk.test.lib.RandomFactory; - -public class SymmetricRangeTests { - - private static final BigInteger MAX_VALUE = makeMaxValue(); - private static final BigInteger MIN_VALUE = MAX_VALUE.negate(); - - private static BigInteger makeMaxValue() { - byte[] ba = new byte[1 << 28]; - Arrays.fill(ba, (byte) 0xFF); - ba[0] = (byte) 0x7F; - return new BigInteger(ba); - } - - private static void check(String msg, BigInteger actual, BigInteger expected) { - if (!actual.equals(expected)) { - throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength()); - } - } - - private static void check(String msg, double actual, double expected) { - if (actual != expected) { - throw new RuntimeException(msg + "=" + actual); - } - } - - private static void check(String msg, float actual, float expected) { - if (actual != expected) { - throw new RuntimeException(msg + "=" + actual); - } - } - - private static void check(String msg, long actual, long expected) { - if (actual != expected) { - throw new RuntimeException(msg + "=" + actual); - } - } - - private static void check(String msg, int actual, int expected) { - if (actual != expected) { - throw new RuntimeException(msg + "=" + actual); - } - } - - private static void testOverflowInMakePositive() { - System.out.println("Testing overflow in BigInteger.makePositive"); - byte[] ba = new byte[Integer.MAX_VALUE - 2]; - ba[0] = (byte) 0x80; - try { - BigInteger actual = new BigInteger(ba); - throw new RuntimeException("new BigInteger(ba).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testBug8021204() { - System.out.println("Testing Bug 8021204"); - StringBuilder sb = new StringBuilder(); - sb.append('1'); - for (int i = 0; i < (1 << 30) - 1; i++) { - sb.append('0'); - } - sb.append('1'); - String s = sb.toString(); - sb = null; - try { - BigInteger actual = new BigInteger(s, 16); - throw new RuntimeException("new BigInteger(\"1000...001\").bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testOverflowInBitSieve() { - System.out.println("Testing overflow in BitSieve.sieveSingle"); - int bitLength = (5 << 27) - 1; - try { - Random random = RandomFactory.getRandom(); - BigInteger actual = new BigInteger(bitLength, 0, random); - throw new RuntimeException("new BigInteger(bitLength, 0, null).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger bi = BigInteger.ONE.shiftLeft(bitLength - 1).subtract(BigInteger.ONE); - BigInteger actual = bi.nextProbablePrime(); - throw new RuntimeException("bi.nextActualPrime().bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testAdd() { - System.out.println("Testing BigInteger.add"); - try { - BigInteger actual = MAX_VALUE.add(BigInteger.ONE); - throw new RuntimeException("BigInteger.MAX_VALUE.add(BigInteger.ONE).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testSubtract() { - System.out.println("Testing BigInteger.subtract"); - try { - BigInteger actual = MIN_VALUE.subtract(BigInteger.ONE); - throw new RuntimeException("BigInteger.MIN_VALUE.subtract(BigInteger.ONE).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testMultiply() { - System.out.println("Testing BigInteger.multiply"); - int py = 2000; - int px = Integer.MAX_VALUE - py; - BigInteger x = BigInteger.ONE.shiftLeft(px); - BigInteger y = BigInteger.ONE.shiftLeft(py); - try { - BigInteger actual = x.multiply(y); - throw new RuntimeException("(1 << " + px + " ) * (1 << " + py + ").bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testDivide() { - System.out.println("Testing BigInteger.divide"); - check("BigInteger.MIN_VALUE.divide(BigInteger.valueOf(-1))", - MIN_VALUE.divide(BigInteger.valueOf(-1)), MAX_VALUE); - check("BigInteger.MIN_VALUE.divide(BigInteger.ONE)", - MIN_VALUE.divide(BigInteger.ONE), MIN_VALUE); - } - - private static void testDivideAndRemainder(String msg, BigInteger dividend, BigInteger divisor, - BigInteger expectedQuotent, BigInteger expectedRemainder) { - BigInteger[] qr = dividend.divideAndRemainder(divisor); - check(msg + "[0]", qr[0], expectedQuotent); - check(msg + "[1]", qr[1], expectedRemainder); - } - - private static void testDivideAndRemainder() { - System.out.println("Testing BigInteger.divideAndRemainder"); - testDivideAndRemainder("BigInteger.MIN_VALUE.divideAndRemainder(BigInteger.valueOf(-1))", - MIN_VALUE, BigInteger.valueOf(-1), - MAX_VALUE, - BigInteger.ZERO); - } - - private static void testBug9005933() { - System.out.println("Testing Bug 9005933"); - int dividendPow = 2147483646; - int divisorPow = 1568; - BigInteger dividend = BigInteger.ONE.shiftLeft(dividendPow); - BigInteger divisor = BigInteger.ONE.shiftLeft(divisorPow); - testDivideAndRemainder("(1 << " + dividendPow + ").divideAndRemainder(1 << " + divisorPow + ")", - dividend, divisor, - BigInteger.ONE.shiftLeft(dividendPow - divisorPow), - BigInteger.ZERO); - } - - private static void testRemainder() { - System.out.println("Testing BigInteger.remainder"); - check("BigInteger.MIN_VALUE.remainder(BigInteger.valueOf(-1))", - MIN_VALUE.remainder(BigInteger.valueOf(-1)), BigInteger.ZERO); - } - - private static void testPow() { - System.out.println("Testing BigInteger.pow"); - check("BigInteger.MIN_VALUE.pow(1)", - MIN_VALUE.pow(1), MIN_VALUE); - try { - BigInteger actual = BigInteger.valueOf(4).pow(Integer.MAX_VALUE); - throw new RuntimeException("BigInteger.valueOf(4).pow(Integer.MAX_VALUE).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testGcd() { - System.out.println("Testing BigInteger.gcd"); - check("BigInteger.MIN_VALUE.gcd(BigInteger.MIN_VALUE)", - MIN_VALUE.gcd(MIN_VALUE), MAX_VALUE); - check("BigInteger.MIN_VALUE.gcd(BigInteger.ZERO)", - MIN_VALUE.gcd(BigInteger.ZERO), MAX_VALUE); - check("BigInteger.ZERO.gcd(MIN_VALUE)", - BigInteger.ZERO.gcd(MIN_VALUE), MAX_VALUE); - } - - private static void testAbs() { - System.out.println("Testing BigInteger.abs"); - check("BigInteger.MIN_VALUE.abs()", - MIN_VALUE.abs(), MAX_VALUE); - check("BigInteger.MAX_VALUE.abs()", - MAX_VALUE.abs(), MAX_VALUE); - } - - private static void testNegate() { - System.out.println("Testing BigInteger.negate"); - check("BigInteger.MIN_VALUE.negate()", - MIN_VALUE.negate(), MAX_VALUE); - check("BigInteger.MAX_VALUE.negate()", - MAX_VALUE.negate(), MIN_VALUE); - } - - private static void testMod() { - System.out.println("Testing BigInteger.mod"); - check("BigInteger.MIN_VALUE.mod(BigInteger.MAX_VALUE)", - MIN_VALUE.mod(MAX_VALUE), BigInteger.ZERO); - check("BigInteger.MAX_VALUE.mod(BigInteger.MAX_VALUE)", - MIN_VALUE.mod(MAX_VALUE), BigInteger.ZERO); - } - - private static void testModPow() { - System.out.println("Testing BigInteger.modPow"); - BigInteger x = BigInteger.valueOf(3); - BigInteger m = BigInteger.valueOf(-4).subtract(MIN_VALUE); - check("BigInteger.valueOf(3).modPow(BigInteger.ONE, m)", - x.modPow(BigInteger.ONE, m), x); - } - - // slow test - private static void testModInverse() { - System.out.println("Testing BigInteger.modInverse"); - check("BigInteger.MIN_VALUE.modInverse(BigInteger.MAX_VALUE)", - MIN_VALUE.modInverse(MAX_VALUE), MAX_VALUE.subtract(BigInteger.ONE)); - } - - private static void testShiftLeft() { - System.out.println("Testing BigInteger.shiftLeft"); - try { - BigInteger actual = MIN_VALUE.shiftLeft(1); - throw new RuntimeException("BigInteger.MIN_VALUE.shiftLeft(1).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger actual = MAX_VALUE.shiftLeft(1); - throw new RuntimeException("BigInteger.MAX_VALUE.shiftLeft(1).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testShiftRight() { - System.out.println("Testing BigInteger.shiftRight"); - try { - BigInteger actual = MIN_VALUE.shiftRight(-1); - throw new RuntimeException("BigInteger.MIN_VALUE.shiftRight(-1).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger actual = MAX_VALUE.shiftRight(-1); - throw new RuntimeException("BigInteger.MAX_VALUE.shiftRight(-1).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testAnd() { - System.out.println("Testing BigInteger.and"); - check("BigInteger.MIN_VALUE.and(BigInteger.MIN_VALUE)", - MIN_VALUE.and(MIN_VALUE), MIN_VALUE); - check("BigInteger.MAX_VALUE.and(BigInteger.MAX_VALUE)", - MAX_VALUE.and(MAX_VALUE), MAX_VALUE); - check("BigInteger.MIN_VALUE.and(BigInteger.MAX_VALUE)", - MIN_VALUE.and(MAX_VALUE), BigInteger.ONE); - try { - BigInteger actual = MIN_VALUE.and(BigInteger.valueOf(-2)); - throw new RuntimeException("BigInteger.MIN_VALUE.and(-2)).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testOr() { - System.out.println("Testing BigInteger.or"); - check("BigInteger.MIN_VALUE.or(BigInteger.MIN_VALUE)", - MIN_VALUE.or(MIN_VALUE), MIN_VALUE); - check("BigInteger.MAX_VALUE.or(BigInteger.MAX_VALUE)", - MAX_VALUE.or(MAX_VALUE), MAX_VALUE); - check("BigInteger.MIN_VALUE.and(BigInteger.MAX_VALUE)", - MIN_VALUE.or(MAX_VALUE), BigInteger.valueOf(-1)); - } - - private static void testXor() { - System.out.println("Testing BigInteger.xor"); - check("BigInteger.MIN_VALUE.xor(BigInteger.MIN_VALUE)", - MIN_VALUE.xor(MIN_VALUE), BigInteger.ZERO); - check("BigInteger.MAX_VALUE.xor(BigInteger.MAX_VALUE)", - MAX_VALUE.xor(MAX_VALUE), BigInteger.ZERO); - check("BigInteger.MIN_VALUE.xor(BigInteger.MAX_VALUE)", - MIN_VALUE.xor(MAX_VALUE), BigInteger.valueOf(-2)); - try { - BigInteger actual = MIN_VALUE.xor(BigInteger.ONE); - throw new RuntimeException("BigInteger.MIN_VALUE.xor(BigInteger.ONE)).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testNot() { - System.out.println("Testing BigInteger.not"); - check("BigInteger.MIN_VALUE.not()", - MIN_VALUE.not(), MAX_VALUE.subtract(BigInteger.ONE)); - try { - BigInteger actual = MAX_VALUE.not(); - throw new RuntimeException("BigInteger.MAX_VALUE.not()).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testSetBit() { - System.out.println("Testing BigInteger.setBit"); - check("BigInteger.MIN_VALUE.setBit(" + Integer.MAX_VALUE + ")", - MIN_VALUE.setBit(Integer.MAX_VALUE), MIN_VALUE); - try { - BigInteger actual = MAX_VALUE.setBit(Integer.MAX_VALUE); - throw new RuntimeException("BigInteger.MAX_VALUE.setBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testClearBit() { - System.out.println("Testing BigInteger.clearBit"); - check("BigInteger.MAX_VALUE.clearBit(" + Integer.MAX_VALUE + ")", - MAX_VALUE.clearBit(Integer.MAX_VALUE), MAX_VALUE); - try { - BigInteger actual = MIN_VALUE.clearBit(Integer.MAX_VALUE); - throw new RuntimeException("BigInteger.MIN_VALUE.clearBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger actual = MIN_VALUE.clearBit(0); - throw new RuntimeException("BigInteger.MIN_VALUE.clearBit(0).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testFlipBit() { - System.out.println("Testing BigInteger.flipBit"); - try { - BigInteger actual = MIN_VALUE.flipBit(Integer.MAX_VALUE); - throw new RuntimeException("BigInteger.MIN_VALUE.flipBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger actual = MIN_VALUE.flipBit(0); - throw new RuntimeException("BigInteger.MIN_VALUE.flipBit(0).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger actual = MAX_VALUE.flipBit(Integer.MAX_VALUE); - throw new RuntimeException("BigInteger.MAX_VALUE.flipBit(" + Integer.MAX_VALUE + ").bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testGetLowestSetBit() { - System.out.println("Testing BigInteger.getLowestSetBit"); - check("BigInteger.MIN_VALUE.getLowestSetBit()", - MIN_VALUE.getLowestSetBit(), 0); - check("BigInteger.MAX_VALUE.getLowestSetBit()", - MAX_VALUE.getLowestSetBit(), 0); - } - - private static void testBitLength() { - System.out.println("Testing BigInteger.bitLength"); - check("BigInteger.MIN_NEXT.bitLength()", - MIN_VALUE.bitLength(), Integer.MAX_VALUE); - check("BigInteger.MAX_VALUE.bitLength()", - MAX_VALUE.bitLength(), Integer.MAX_VALUE); - } - - private static void testBitCount() { - System.out.println("Testing BigInteger.bitCount"); - check("BigInteger.MIN_VALUE.bitCount()", - MIN_VALUE.bitCount(), Integer.MAX_VALUE - 1); - check("BigInteger.MAX_VALUE.bitCount()", - MAX_VALUE.bitCount(), Integer.MAX_VALUE); - } - - private static void testToString(String msg, int radix, BigInteger bi, int length, String startsWith, char c) { - String s = bi.toString(radix); - if (s.length() != length) { - throw new RuntimeException(msg + ".length=" + s.length()); - } - if (!s.startsWith(startsWith)) { - throw new RuntimeException(msg + "[0]=" + s.substring(0, startsWith.length())); - } - for (int i = startsWith.length(); i < s.length(); i++) { - if (s.charAt(i) != c) { - throw new RuntimeException(msg + "[" + i + "]='" + s.charAt(i) + "'"); - } - } - } - - private static void testToString() { - System.out.println("Testing BigInteger.toString"); - testToString("BigInteger.MIN_VALUE.toString(16)=", 16, - BigInteger.valueOf(-1).shiftLeft(Integer.MAX_VALUE - 1), - (1 << 29) + 1, "-4", '0'); - } - - private static void testToByteArrayWithConstructor(String msg, BigInteger bi, int length, byte msb, byte b, byte lsb) { - byte[] ba = bi.toByteArray(); - if (ba.length != length) { - throw new RuntimeException(msg + ".length=" + ba.length); - } - if (ba[0] != msb) { - throw new RuntimeException(msg + "[0]=" + ba[0]); - } - for (int i = 1; i < ba.length - 1; i++) { - if (ba[i] != b) { - throw new RuntimeException(msg + "[" + i + "]=" + ba[i]); - } - } - if (ba[ba.length - 1] != lsb) { - throw new RuntimeException(msg + "[" + (ba.length - 1) + "]=" + ba[ba.length - 1]); - } - BigInteger actual = new BigInteger(ba); - if (!actual.equals(bi)) { - throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength()); - } - } - - private static void testToByteArrayWithConstructor() { - System.out.println("Testing BigInteger.toByteArray with constructor"); - testToByteArrayWithConstructor("BigInteger.MIN_VALUE.toByteArray()", - MIN_VALUE, (1 << 28), (byte) 0x80, (byte) 0x00, (byte) 0x01); - testToByteArrayWithConstructor("BigInteger.MAX_VALUE.toByteArray()", - MAX_VALUE, (1 << 28), (byte) 0x7f, (byte) 0xff, (byte) 0xff); - - byte[] ba = new byte[1 << 28]; - ba[0] = (byte) 0x80; - try { - BigInteger actual = new BigInteger(-1, ba); - throw new RuntimeException("new BigInteger(-1, ba).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - try { - BigInteger actual = new BigInteger(1, ba); - throw new RuntimeException("new BigInteger(1, ba).bitLength()=" + actual.bitLength()); - } catch (ArithmeticException e) { - // expected - } - } - - private static void testIntValue() { - System.out.println("Testing BigInteger.intValue"); - check("BigInteger.MIN_VALUE.intValue()", - MIN_VALUE.intValue(), 1); - check("BigInteger.MAX_VALUE.floatValue()", - MAX_VALUE.intValue(), -1); - } - - private static void testLongValue() { - System.out.println("Testing BigInteger.longValue"); - check("BigInteger.MIN_VALUE.longValue()", - MIN_VALUE.longValue(), 1L); - check("BigInteger.MAX_VALUE.longValue()", - MAX_VALUE.longValue(), -1L); - } - - private static void testFloatValue() { - System.out.println("Testing BigInteger.floatValue, Bug 8021203"); - check("BigInteger.MIN_VALUE_.floatValue()", - MIN_VALUE.floatValue(), Float.NEGATIVE_INFINITY); - check("BigInteger.MAX_VALUE.floatValue()", - MAX_VALUE.floatValue(), Float.POSITIVE_INFINITY); - } - - private static void testDoubleValue() { - System.out.println("Testing BigInteger.doubleValue, Bug 8021203"); - check("BigInteger.MIN_VALUE.doubleValue()", - MIN_VALUE.doubleValue(), Double.NEGATIVE_INFINITY); - check("BigInteger.MAX_VALUE.doubleValue()", - MAX_VALUE.doubleValue(), Double.POSITIVE_INFINITY); - } - - private static void testSerialization(String msg, BigInteger bi) { - try { - ByteArrayOutputStream baOut = new ByteArrayOutputStream((1 << 28) + 1000); - ObjectOutputStream out = new ObjectOutputStream(baOut); - out.writeObject(bi); - out.close(); - out = null; - byte[] ba = baOut.toByteArray(); - baOut = null; - ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(ba)); - BigInteger actual = (BigInteger) in.readObject(); - if (!actual.equals(bi)) { - throw new RuntimeException(msg + ".bitLength()=" + actual.bitLength()); - } - } catch (IOException | ClassNotFoundException e) { - throw new RuntimeException(msg + " raised exception ", e); - } - } - - private static void testSerialization() { - System.out.println("Testing BigInteger serialization"); - testSerialization("BigInteger.MIN_VALUE.intValue()", - MIN_VALUE); - testSerialization("BigInteger.MAX_VALUE.floatValue()", - MAX_VALUE); - } - - private static void testLongValueExact() { - System.out.println("Testing BigInteger.longValueExact"); - try { - long actual = MIN_VALUE.longValueExact(); - throw new RuntimeException("BigInteger.MIN_VALUE.longValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - try { - long actual = MAX_VALUE.longValueExact(); - throw new RuntimeException("BigInteger.MAX_VALUE.longValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - } - - private static void testIntValueExact() { - System.out.println("Testing BigInteger.intValueExact"); - try { - long actual = MIN_VALUE.intValueExact(); - throw new RuntimeException("BigInteger.MIN_VALUE.intValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - try { - long actual = MAX_VALUE.intValueExact(); - throw new RuntimeException("BigInteger.MAX_VALUE.intValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - } - - private static void testShortValueExact() { - System.out.println("Testing BigInteger.shortValueExact"); - try { - long actual = MIN_VALUE.shortValueExact(); - throw new RuntimeException("BigInteger.MIN_VALUE.shortValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - try { - long actual = MAX_VALUE.shortValueExact(); - throw new RuntimeException("BigInteger.MAX_VALUE.shortValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - } - - private static void testByteValueExact() { - System.out.println("Testing BigInteger.byteValueExact"); - try { - long actual = MIN_VALUE.byteValueExact(); - throw new RuntimeException("BigInteger.MIN_VALUE.byteValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - try { - long actual = MAX_VALUE.byteValueExact(); - throw new RuntimeException("BigInteger.MAX_VALUE.byteValueExact()= " + actual); - } catch (ArithmeticException e) { - // excpected - } - } - - public static void main(String... args) { - testOverflowInMakePositive(); - testBug8021204(); - testOverflowInBitSieve(); - testAdd(); - testSubtract(); - testMultiply(); - testDivide(); - testDivideAndRemainder(); - testBug9005933(); - testRemainder(); - testPow(); - testGcd(); - testAbs(); - testNegate(); - testMod(); - testModPow(); -// testModInverse(); - testShiftLeft(); - testShiftRight(); - testAnd(); - testOr(); - testXor(); - testNot(); - testSetBit(); - testClearBit(); - testFlipBit(); - testGetLowestSetBit(); - testBitLength(); - testBitCount(); - testToString(); - testToByteArrayWithConstructor(); - testIntValue(); - testLongValue(); - testFloatValue(); - testDoubleValue(); - testSerialization(); - testLongValueExact(); - testIntValueExact(); - testShortValueExact(); - testByteValueExact(); - } -} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/BindException/Test.java openjdk-lts-11.0.21+9/test/jdk/java/net/BindException/Test.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/BindException/Test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/BindException/Test.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -45,18 +45,24 @@ static int count; static int failures; + static boolean retried; static void doTest(Object test[], InetAddress ia1, InetAddress ia2, boolean silent) throws Exception { - String s1_type = (String)test[0]; - String s2_type = (String)test[1]; - int port = 0; - /* * Increment test count */ count++; + doTest(test, count, ia1, ia2, silent, !retried); + } + + static void doTest(Object test[], int count, InetAddress ia1, InetAddress ia2, + boolean silent, boolean retry) throws Exception { + String s1_type = (String)test[0]; + String s2_type = (String)test[1]; + int port = 0; + /* * Do the test */ @@ -68,6 +74,8 @@ Socket sock1 = null; ServerSocket ss = null; DatagramSocket dsock1 = null; + boolean firstBound = false; + try { /* bind the first socket */ @@ -89,6 +97,13 @@ /* bind the second socket */ + // The fact that the port was available for ia1 does not + // guarantee that it will also be available for ia2 as something + // else might already be bound to that port. + // For the sake of test stability we will retry once in + // case of unexpected bind exception. + + firstBound = true; if (s2_type.equals("Socket")) { try (Socket sock2 = new Socket()) { sock2.bind( new InetSocketAddress(ia2, port)); @@ -141,6 +156,18 @@ return; } + if (failed && retry && firstBound) { + // retry once at the first failure only + retried = true; + if (!silent) { + System.out.println(""); + System.out.println("**************************"); + System.out.println("Test " + count + ": Retrying..."); + } + doTest(test, count, ia1, ia2, silent, false); + return; + } + if (failed || !silent) { System.out.println(""); System.out.println("**************************"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java openjdk-lts-11.0.21+9/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/DatagramSocket/UnreferencedDatagramSockets.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -48,6 +48,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; +import java.util.concurrent.CountDownLatch; import com.sun.management.UnixOperatingSystemMXBean; @@ -67,9 +68,10 @@ static class Server implements Runnable { DatagramSocket ss; + CountDownLatch latch = new CountDownLatch(1); Server() throws IOException { - ss = new DatagramSocket(0); + ss = new DatagramSocket(0, getHost()); System.out.printf(" DatagramServer addr: %s: %d%n", this.getHost(), this.getPort()); pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverDatagramSocket")); @@ -77,7 +79,7 @@ } InetAddress getHost() throws UnknownHostException { - InetAddress localhost = InetAddress.getByName("localhost"); //.getLocalHost(); + InetAddress localhost = lookupLocalHost(); return localhost; } @@ -93,7 +95,7 @@ ss.receive(p); buffer[0] += 1; ss.send(p); // send back +1 - + latch.await(); // wait for the client to receive the packet // do NOT close but 'forget' the datagram socket reference ss = null; } catch (Exception ioe) { @@ -102,10 +104,14 @@ } } + static InetAddress lookupLocalHost() throws UnknownHostException { + return InetAddress.getByName("localhost"); //.getLocalHost(); + } + public static void main(String args[]) throws Exception { // Create and close a DatagramSocket to warm up the FD count for side effects. - try (DatagramSocket s = new DatagramSocket(0)) { + try (DatagramSocket s = new DatagramSocket(0, lookupLocalHost())) { // no-op; close immediately s.getLocalPort(); // no-op } @@ -118,7 +124,7 @@ Thread thr = new Thread(svr); thr.start(); - DatagramSocket client = new DatagramSocket(0); + DatagramSocket client = new DatagramSocket(0, lookupLocalHost()); client.connect(svr.getHost(), svr.getPort()); pendingSockets.add(new NamedWeak(client, pendingQueue, "clientDatagramSocket")); extractRefs(client, "clientDatagramSocket"); @@ -130,6 +136,8 @@ p = new DatagramPacket(msg, msg.length); client.receive(p); + svr.latch.countDown(); // unblock the server + System.out.printf("echo received from: %s%n", p.getSocketAddress()); if (msg[0] != 2) { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/httpclient/AuthSchemesTest.java openjdk-lts-11.0.21+9/test/jdk/java/net/httpclient/AuthSchemesTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/httpclient/AuthSchemesTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/httpclient/AuthSchemesTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 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 8217237 + * @modules java.net.http + * @run main/othervm AuthSchemesTest + * @summary HttpClient does not deal well with multi-valued WWW-Authenticate challenge headers + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.net.Authenticator; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; + +public class AuthSchemesTest { + static class BasicServer extends Thread { + + ServerSocket server; + + Socket s; + InputStream is; + OutputStream os; + static final String RESPONSE = "Hello world"; + static final String respLength = Integer.toString(RESPONSE.length()); + static final String realm = "wally world"; + + String reply1 = "HTTP/1.1 401 Unauthorized\r\n"+ + "WWW-Authenticate: BarScheme\r\n" + + "WWW-Authenticate: FooScheme realm=\""+realm+"\"\r\n" + + "WWW-Authenticate: Basic realm=\""+realm+"\"\r\n" + + "WWW-Authenticate: WoofScheme\r\n\r\n"; + + String reply2 = "HTTP/1.1 200 OK\r\n"+ + "Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" + + "Server: Apache/1.3.14 (Unix)\r\n" + + "Connection: close\r\n" + + "Content-Type: text/html; charset=iso-8859-1\r\n" + + "Content-Length: " + respLength + "\r\n\r\n"; + + BasicServer(ServerSocket s) { + server = s; + } + + String response() { + return RESPONSE; + } + + void readAll(Socket s) throws IOException { + byte[] buf = new byte [128]; + InputStream is = s.getInputStream(); + s.setSoTimeout(1000); + try { + while (is.read(buf) > 0) ; + } catch (SocketTimeoutException x) { } + } + + public void run() { + try { + System.out.println("Server 1: accept"); + s = server.accept(); + System.out.println("accepted"); + os = s.getOutputStream(); + os.write(reply1.getBytes()); + readAll(s); + s.close(); + + System.out.println("Server 2: accept"); + s = server.accept(); + System.out.println("accepted"); + os = s.getOutputStream(); + os.write((reply2+RESPONSE).getBytes()); + readAll(s); + s.close(); + + } + catch (Exception e) { + System.out.println(e); + } + finished(); + } + + boolean isfinished = false; + + public synchronized void finished() { + isfinished = true; + notifyAll(); + } + + public synchronized void waitforfinish() { + while (!isfinished) { + try { + wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + static class Auth extends Authenticator { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication("user", new char[] {'a','b','c'}); + } + } + + public static void main(String[] args) throws Exception { + ServerSocket serversocket = null; + BasicServer server = null; + Auth authenticator = new Auth(); + + serversocket = new ServerSocket(0, 10, InetAddress.getLoopbackAddress()); + int port = serversocket.getLocalPort(); + server = new BasicServer(serversocket); + + HttpClient client = HttpClient.newBuilder() + .authenticator(authenticator) + .build(); + server.start(); + URI uri = URI.create("http://127.0.0.1:" + port + "/foo"); + HttpRequest request = HttpRequest.newBuilder(uri) + .GET() + .build(); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200 || !response.body().equals(server.response())) { + System.out.println("Status code = " + response.statusCode()); + serversocket.close(); + throw new RuntimeException("Test failed"); + } + serversocket.close(); + server.waitforfinish(); + System.out.println("OK"); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java openjdk-lts-11.0.21+9/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/HttpURLConnection/SetAuthenticator/HTTPTestServer.java 2023-10-06 05:33:33.000000000 +0000 @@ -978,6 +978,8 @@ implements Runnable { final ServerSocket ss; + private volatile boolean stop; + public HttpsProxyTunnel(HttpServer server, HTTPTestServer target, HttpHandler delegate) throws IOException { @@ -996,9 +998,10 @@ @Override public void stop() { - super.stop(); - try { - ss.close(); + try (var toClose = ss) { + stop = true; + System.out.println("Server " + ss + " stop requested"); + super.stop(); } catch (IOException ex) { if (DEBUG) ex.printStackTrace(System.out); } @@ -1048,6 +1051,9 @@ if (c == '\n') break; b.appendCodePoint(c); } + if (b.length() == 0) { + return ""; + } if (b.codePointAt(b.length() -1) == '\r') { b.delete(b.length() -1, b.length()); } @@ -1057,80 +1063,121 @@ @Override public void run() { Socket clientConnection = null; - try { - while (true) { - System.out.println("Tunnel: Waiting for client at: " + ss); - Socket previous = clientConnection; + while (!stop) { + System.out.println("Tunnel: Waiting for client at: " + ss); + final Socket previous = clientConnection; + try { + clientConnection = ss.accept(); + } catch (IOException io) { try { - clientConnection = ss.accept(); - } catch (IOException io) { - if (DEBUG) io.printStackTrace(System.out); - break; - } finally { - // close the previous connection - if (previous != null) previous.close(); + ss.close(); + } catch (IOException ex) { + if (DEBUG) { + ex.printStackTrace(System.out); + } } - System.out.println("Tunnel: Client accepted"); - Socket targetConnection = null; - InputStream ccis = clientConnection.getInputStream(); - OutputStream ccos = clientConnection.getOutputStream(); - Writer w = new OutputStreamWriter( - clientConnection.getOutputStream(), "UTF-8"); - PrintWriter pw = new PrintWriter(w); - System.out.println("Tunnel: Reading request line"); - String requestLine = readLine(ccis); - System.out.println("Tunnel: Request line: " + requestLine); - if (requestLine.startsWith("CONNECT ")) { - // We should probably check that the next word following - // CONNECT is the host:port of our HTTPS serverImpl. - // Some improvement for a followup! - - // Read all headers until we find the empty line that - // signals the end of all headers. - while(!requestLine.equals("")) { - System.out.println("Tunnel: Reading header: " - + (requestLine = readLine(ccis))); + // log the reason that caused the server to stop accepting connections + if (!stop) { + System.err.println("Server will stop accepting connections due to an exception:"); + io.printStackTrace(); + } + break; + } finally { + // close the previous connection + if (previous != null) { + try { + previous.close(); + } catch (IOException e) { + // ignore + if (DEBUG) { + System.out.println("Ignoring exception that happened while closing " + + "an older connection:"); + e.printStackTrace(System.out); + } } - - targetConnection = new Socket( - serverImpl.getAddress().getAddress(), - serverImpl.getAddress().getPort()); - - // Then send the 200 OK response to the client - System.out.println("Tunnel: Sending " - + "HTTP/1.1 200 OK\r\n\r\n"); - pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); - pw.flush(); - } else { - // This should not happen. If it does let our serverImpl - // deal with it. - throw new IOException("Tunnel: Unexpected status line: " - + requestLine); - } - - // Pipe the input stream of the client connection to the - // output stream of the target connection and conversely. - // Now the client and target will just talk to each other. - System.out.println("Tunnel: Starting tunnel pipes"); - Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+'); - Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-'); - t1.start(); - t2.start(); - - // We have only 1 client... wait until it has finished before - // accepting a new connection request. - t1.join(); - t2.join(); + } } - } catch (Throwable ex) { + System.out.println("Tunnel: Client accepted"); try { - ss.close(); - } catch (IOException ex1) { - ex.addSuppressed(ex1); + // We have only 1 client... process the current client + // request and wait until it has finished before + // accepting a new connection request. + processRequestAndWaitToComplete(clientConnection); + } catch (IOException ioe) { + // close the client connection + try { + clientConnection.close(); + } catch (IOException io) { + // ignore + if (DEBUG) { + System.out.println("Ignoring exception that happened during client" + + " connection close:"); + io.printStackTrace(System.out); + } + } finally { + clientConnection = null; + } + } catch (Throwable t) { + // don't close the client connection for non-IOExceptions, instead + // just log it and move on to accept next connection + if (!stop) { + t.printStackTrace(); + } } - ex.printStackTrace(System.err); } } + private void processRequestAndWaitToComplete(final Socket clientConnection) + throws IOException, InterruptedException { + final Socket targetConnection; + InputStream ccis = clientConnection.getInputStream(); + OutputStream ccos = clientConnection.getOutputStream(); + Writer w = new OutputStreamWriter( + clientConnection.getOutputStream(), "UTF-8"); + PrintWriter pw = new PrintWriter(w); + System.out.println("Tunnel: Reading request line"); + String requestLine = readLine(ccis); + System.out.println("Tunnel: Request line: " + requestLine); + if (requestLine.startsWith("CONNECT ")) { + // We should probably check that the next word following + // CONNECT is the host:port of our HTTPS serverImpl. + // Some improvement for a followup! + + // Read all headers until we find the empty line that + // signals the end of all headers. + while(!requestLine.equals("")) { + System.out.println("Tunnel: Reading header: " + + (requestLine = readLine(ccis))); + } + + targetConnection = new Socket( + serverImpl.getAddress().getAddress(), + serverImpl.getAddress().getPort()); + + // Then send the 200 OK response to the client + System.out.println("Tunnel: Sending " + + "HTTP/1.1 200 OK\r\n\r\n"); + pw.print("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n"); + pw.flush(); + } else { + // This should not happen. If it does then consider it a + // client error and throw an IOException + System.out.println("Tunnel: Throwing an IOException due to unexpected" + + " request line: " + requestLine); + throw new IOException("Client request error - Unexpected request line"); + } + + // Pipe the input stream of the client connection to the + // output stream of the target connection and conversely. + // Now the client and target will just talk to each other. + System.out.println("Tunnel: Starting tunnel pipes"); + Thread t1 = pipe(ccis, targetConnection.getOutputStream(), '+'); + Thread t2 = pipe(targetConnection.getInputStream(), ccos, '-'); + t1.start(); + t2.start(); + // wait for the request to complete + t1.join(); + t2.join(); + } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/InetAddress/ptr/Lookup.java openjdk-lts-11.0.21+9/test/jdk/java/net/InetAddress/ptr/Lookup.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/InetAddress/ptr/Lookup.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/InetAddress/ptr/Lookup.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -42,6 +42,8 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; +import java.util.stream.Stream; +import java.util.stream.Collectors; import jdk.test.lib.JDKToolFinder; import jdk.test.lib.process.OutputAnalyzer; @@ -55,40 +57,80 @@ public static void main(String args[]) throws IOException { String addr = null; String ipv4Name = null; + String ipv4Reversed = null; + if (args.length == 0) { - // First check that host resolves to IPv4 address + // called from lookupWithIPv4Prefer + // obtain an IPv4 address from the hostname. try { InetAddress ia = InetAddress.getByName(HOST); addr = ia.getHostAddress(); + ia = InetAddress.getByName(addr); + System.out.print(addr + ":" + ia.getHostName()); + return; } catch (UnknownHostException e) { System.out.print(SKIP); return; } - } else { - String tmp = lookupWithIPv4Prefer(); - System.out.println("IPv4 lookup results: [" + tmp + "]"); - if (SKIP.equals(tmp)) { - System.out.println(HOST + " can't be resolved - test skipped."); + } else if (args.length == 2 && args[0].equals("reverse")) { + // called from reverseWithIPv4Prefer + // Check that IPv4 address can be resolved to host + // with -Djava.net.preferIPv4Stack=true + try { + InetAddress ia = InetAddress.getByName(args[1]); + addr = ia.getHostAddress(); + ipv4Reversed = ia.getHostName(); + System.out.print(addr + ":" + ipv4Reversed); + return; + } catch (UnknownHostException e) { + System.out.print(SKIP); return; } + } else if (args.length != 1 || !args[0].equals("root")) { + throw new IllegalArgumentException(Stream.of(args).collect(Collectors.joining(" "))); + } + + // spawn a subprocess to obtain the IPv4 address + String tmp = lookupWithIPv4Prefer(); + System.out.println("IPv4 lookup results: [" + tmp + "]"); + if (SKIP.equals(tmp)) { + System.out.println(HOST + " can't be resolved - test skipped."); + return; + } - String[] strs = tmp.split(":"); - addr = strs[0]; - ipv4Name = strs[1]; + String[] strs = tmp.split(":"); + addr = strs[0]; + ipv4Name = strs[1]; + + // check that the a reverse lookup of the IPv4 address + // will succeed with the IPv4 only stack + tmp = reverseWithIPv4Prefer(addr); + System.out.println("IPv4 reverse lookup results: [" + tmp + "]"); + if (SKIP.equals(tmp)) { + System.out.println(addr + " can't be resolved with preferIPv4 - test skipped."); + return; } - // reverse lookup + strs = tmp.split(":"); + ipv4Reversed = strs[1]; + + // Now check that a reverse lookup will succeed with the dual stack. InetAddress ia = InetAddress.getByName(addr); String name = ia.getHostName(); - if (args.length == 0) { - System.out.print(addr + ":" + name); - return; - } else { - System.out.println("(default) " + addr + "--> " + name); - if (!ipv4Name.equals(name)) { - throw new RuntimeException("Mismatch between default" - + " and java.net.preferIPv4Stack=true results"); + + System.out.println("(default) " + addr + "--> " + name + + " (reversed IPv4: " + ipv4Reversed + ")"); + if (!ipv4Name.equals(name)) { + // adding some diagnosting + System.err.println("name=" + name + " doesn't match expected=" + ipv4Name); + System.err.println("Listing all adresses:"); + for (InetAddress any : InetAddress.getAllByName(HOST)) { + System.err.println("\t[" + any + "] address=" + any.getHostAddress() + + ", host=" + any.getHostName()); } + // make the test fail... + throw new RuntimeException("Mismatch between default" + + " and java.net.preferIPv4Stack=true results"); } } @@ -100,5 +142,13 @@ System.out.println("Executing: " + cmd); return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput(); } -} + static String reverseWithIPv4Prefer(String addr) throws IOException { + String java = JDKToolFinder.getTestJDKTool("java"); + String testClz = Lookup.class.getName(); + List cmd = List.of(java, "-Djava.net.preferIPv4Stack=true", + "-cp", CLASS_PATH, testClz, "reverse", addr); + System.out.println("Executing: " + cmd); + return new OutputAnalyzer(new ProcessBuilder(cmd).start()).getOutput(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/ipv6tests/UdpTest.java openjdk-lts-11.0.21+9/test/jdk/java/net/ipv6tests/UdpTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/ipv6tests/UdpTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/ipv6tests/UdpTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -24,11 +24,14 @@ /* * @test * @bug 4868820 - * @summary IPv6 support for Windows XP and 2003 server + * @key intermittent + * @summary IPv6 support for Windows XP and 2003 server. + * This test requires binding to the wildcard address and as such + * may fail intermittently on some platforms. * @library /test/lib * @build jdk.test.lib.NetworkConfiguration * jdk.test.lib.Platform - * @run main UdpTest + * @run main UdpTest -d */ import java.net.DatagramPacket; @@ -88,6 +91,7 @@ /* basic UDP connectivity test using IPv6 only and IPv4/IPv6 together */ static void test1 () throws Exception { + System.out.println("Test1 starting"); s1 = new DatagramSocket (); s2 = new DatagramSocket (); simpleDataExchange (s1, ia4addr, s2, ia4addr); @@ -126,6 +130,7 @@ /* check timeouts on receive */ static void test2 () throws Exception { + System.out.println("Test2 starting"); s1 = new DatagramSocket (); s2 = new DatagramSocket (); s1.setSoTimeout (4000); @@ -176,6 +181,7 @@ /* check connected sockets */ static void test3 () throws Exception { + System.out.println("Test3 starting"); s1 = new DatagramSocket (); s2 = new DatagramSocket (); s1.connect (ia6addr, s2.getLocalPort()); @@ -187,6 +193,7 @@ /* check PortUnreachable */ static void test4 () throws Exception { + System.out.println("Test4 starting"); s1 = new DatagramSocket (); s1.connect (ia6addr, 5000); s1.setSoTimeout (3000); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java openjdk-lts-11.0.21+9/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/NetworkInterface/NetworkInterfaceRetrievalTests.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,12 +23,14 @@ /** * @test + * @library /test/lib * @bug 8179559 */ import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Enumeration; +import jdk.test.lib.Platform; public class NetworkInterfaceRetrievalTests { public static void main(String[] args) throws Exception { @@ -39,6 +41,12 @@ .getNetworkInterfaces(); while (en.hasMoreElements()) { NetworkInterface ni = en.nextElement(); + + //JDK-8230132: Should not test on Windows with Teredo Tunneling Pseudo-Interface + String dName = ni.getDisplayName(); + if (Platform.isWindows() && dName != null && dName.contains("Teredo")) + continue; + Enumeration addrs = ni.getInetAddresses(); System.out.println("############ Checking network interface + " + ni + " #############"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/PlainSocketImpl/SetOption.java openjdk-lts-11.0.21+9/test/jdk/java/net/PlainSocketImpl/SetOption.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/PlainSocketImpl/SetOption.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/PlainSocketImpl/SetOption.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -35,8 +35,10 @@ public static void main(String args[]) throws Exception { - ServerSocket ss = new ServerSocket(0); - Socket s1 = new Socket("localhost", ss.getLocalPort()); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(0, 0, loopback); + + Socket s1 = new Socket(loopback, ss.getLocalPort()); Socket s2 = ss.accept(); s1.close(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/SctpSanity.java openjdk-lts-11.0.21+9/test/jdk/java/net/SctpSanity.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/SctpSanity.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/SctpSanity.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 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 8232097 + * @summary Basic sanity for creation of SCTP channels + * @modules jdk.sctp + * @run main/othervm SctpSanity 1 + * @run main/othervm SctpSanity 2 + * @run main/othervm SctpSanity 3 + */ + +import java.io.IOException; +import com.sun.nio.sctp.SctpChannel; +import com.sun.nio.sctp.SctpMultiChannel; +import com.sun.nio.sctp.SctpServerChannel; +import static java.lang.System.out; + +/** + * Tests creation of SCTP channels. The channels should either be created + * or not. The latter throwing an UnsupportedOperationException. No other + * behavior is acceptable. Minimally, exercises the JDK's native library + * loading on operating systems that provide an implementation, even if + * the system-level support is not configured. + */ +public class SctpSanity { + + public static void main(String... args) throws IOException { + switch (Integer.valueOf(args[0])) { + case 1: testSctpChannel(); break; + case 2: testSctpServerChannel(); break; + case 3: testSctpMultiChannel(); break; + default: throw new AssertionError("should not reach here"); + } + } + + static void testSctpChannel() throws IOException { + try (SctpChannel channel = SctpChannel.open()) { + out.println("created SctpChannel:" + channel); + } catch (UnsupportedOperationException uoe) { + // ok - the platform does not support SCTP + out.println("ok, caught:" + uoe); + } + } + + static void testSctpServerChannel() throws IOException { + try (SctpServerChannel channel = SctpServerChannel.open()) { + out.println("created SctpServerChannel:" + channel); + } catch (UnsupportedOperationException uoe) { + // ok - the platform does not support SCTP + out.println("ok, caught:" + uoe); + } + } + + static void testSctpMultiChannel() throws IOException { + try (SctpMultiChannel channel = SctpMultiChannel.open()) { + out.println("created SctpMultiChannel:" + channel); + } catch (UnsupportedOperationException uoe) { + // ok - the platform does not support SCTP + out.println("ok, caught:" + uoe); + } + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/Socket/RST.java openjdk-lts-11.0.21+9/test/jdk/java/net/Socket/RST.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/Socket/RST.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/Socket/RST.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -44,8 +44,10 @@ } RST() throws Exception { - ServerSocket ss = new ServerSocket(0); - client = new Socket("localhost", ss.getLocalPort()); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); + client = new Socket(loopback, ss.getLocalPort()); Socket server = ss.accept(); Thread thr = new Thread(this); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/Socket/Streams.java openjdk-lts-11.0.21+9/test/jdk/java/net/Socket/Streams.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/Socket/Streams.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/Socket/Streams.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -29,6 +29,8 @@ import java.io.IOException; import java.lang.reflect.Constructor; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.Phaser; @@ -42,7 +44,9 @@ public static void main(String[] args) throws Exception { - try (ServerSocket ss = new ServerSocket(0)) { + try (ServerSocket ss = new ServerSocket()) { + InetAddress loopback = InetAddress.getLoopbackAddress(); + ss.bind(new InetSocketAddress(loopback, 0)); runTest(OutputStreamGetter.class, ss); runTest(InputStreamGetter.class, ss); } @@ -55,9 +59,12 @@ throws Exception { final int port = ss.getLocalPort(); + final InetAddress address = ss.getInetAddress(); Socket[] sockets = new Socket[NUM_THREADS]; for (int i=0; i { @@ -120,8 +126,6 @@ @Test(groups = "unit") public void testSocksOverIPv6() throws Exception { - if (!shouldRun) return; - Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("::1", socks.getPort())); URL url = new URL("http://[::1]:" + server.getAddress().getPort()); @@ -136,8 +140,6 @@ @Test(groups = "unit") public void testSocksOverIPv6Hostname() throws Exception { - if (!shouldRun) return; - InetAddress ipv6Loopback = InetAddress.getByName("::1"); String ipv6Hostname = ipv6Loopback.getHostName(); String ipv6HostAddress = ipv6Loopback.getHostAddress(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/net/URLConnection/URLConnectionHeaders.java openjdk-lts-11.0.21+9/test/jdk/java/net/URLConnection/URLConnectionHeaders.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/net/URLConnection/URLConnectionHeaders.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/net/URLConnection/URLConnectionHeaders.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -27,12 +27,14 @@ * @summary URLConnection cannot enumerate request properties, * and URLConnection can neither get nor set multiple * request properties w/ same key + * @library /test/lib * */ import java.net.*; import java.util.*; import java.io.*; +import jdk.test.lib.net.URIBuilder; public class URLConnectionHeaders { @@ -77,15 +79,22 @@ } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { try { - ServerSocket serversocket = new ServerSocket (0); - int port = serversocket.getLocalPort (); - XServer server = new XServer (serversocket); - server.start (); - Thread.sleep (200); - URL url = new URL ("http://localhost:"+port+"/index.html"); - URLConnection uc = url.openConnection (); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ServerSocket serversocket = new ServerSocket(); + serversocket.bind(new InetSocketAddress(loopback, 0)); + int port = serversocket.getLocalPort(); + XServer server = new XServer(serversocket); + server.start(); + Thread.sleep(200); + URL url = URIBuilder.newBuilder() + .scheme("http") + .loopback() + .port(port) + .path("/index.html") + .toURL(); + URLConnection uc = url.openConnection(); // add request properties uc.addRequestProperty("Cookie", "cookie1"); @@ -106,6 +115,7 @@ } catch (Exception e) { e.printStackTrace(); + throw e; } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/nio/Buffer/Basic.java openjdk-lts-11.0.21+9/test/jdk/java/nio/Buffer/Basic.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/nio/Buffer/Basic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/nio/Buffer/Basic.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,7 +26,7 @@ * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725 * 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 6231529 * 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 8065556 - * 8149469 + * 8149469 8230665 * @modules java.base/java.nio:open * java.base/jdk.internal.misc * @author Mark Reinhold diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/nio/charset/Charset/DefaultCharsetTest.java openjdk-lts-11.0.21+9/test/jdk/java/nio/charset/Charset/DefaultCharsetTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/nio/charset/Charset/DefaultCharsetTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/nio/charset/Charset/DefaultCharsetTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -54,7 +54,7 @@ public class DefaultCharsetTest { private static final ProcessBuilder pb - = ProcessTools.createJavaProcessBuilder(true, Default.class.getName()); + = ProcessTools.createTestJvm(Default.class.getName()); private static final Map env = pb.environment(); private static String UNSUPPORTED = null; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/nio/charset/coders/SJISMappingPropTest.java openjdk-lts-11.0.21+9/test/jdk/java/nio/charset/coders/SJISMappingPropTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/nio/charset/coders/SJISMappingPropTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/nio/charset/coders/SJISMappingPropTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -81,7 +81,7 @@ } private void runTest(String locale, String... cmd) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmd); + ProcessBuilder pb = ProcessTools.createTestJvm(cmd); Map env = pb.environment(); env.put("LC_ALL", locale); OutputAnalyzer out = ProcessTools.executeProcess(pb) diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/nio/file/FileStore/Basic.java openjdk-lts-11.0.21+9/test/jdk/java/nio/file/FileStore/Basic.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/nio/file/FileStore/Basic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/nio/file/FileStore/Basic.java 2023-10-06 05:33:33.000000000 +0000 @@ -124,7 +124,7 @@ /** * Test: Enumerate all FileStores */ - if (FileUtils.areFileSystemsAccessible()) { + if (FileUtils.areAllMountPointsAccessible()) { FileStore prev = null; for (FileStore store: FileSystems.getDefault().getFileStores()) { System.out.format("%s (name=%s type=%s)\n", store, store.name(), diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/nio/file/Path/MacPathTest.java openjdk-lts-11.0.21+9/test/jdk/java/nio/file/Path/MacPathTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/nio/file/Path/MacPathTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/nio/file/Path/MacPathTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -41,7 +41,7 @@ public class MacPathTest { public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, MacPath.class.getName()); + ProcessBuilder pb = ProcessTools.createTestJvm(MacPath.class.getName()); pb.environment().put("LC_ALL", "en_US.UTF-8"); ProcessTools.executeProcess(pb) .outputTo(System.out) Binary files /tmp/tmpqf9nh9_e/WmtU8sFA5F/openjdk-lts-11.0.20.1+1/test/jdk/java/security/KeyRep/RSA.pre.1.5.key and /tmp/tmpqf9nh9_e/hxiu8P4Qky/openjdk-lts-11.0.21+9/test/jdk/java/security/KeyRep/RSA.pre.1.5.key differ diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/KeyRep/SerialOld.java openjdk-lts-11.0.21+9/test/jdk/java/security/KeyRep/SerialOld.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/KeyRep/SerialOld.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/KeyRep/SerialOld.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, 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 @@ -23,14 +23,13 @@ /* * @test 1.1, 03/08/13 - * @bug 4532506 + * @bug 4532506 8301126 * @summary Serializing KeyPair on one VM (Sun), * and Deserializing on another (IBM) fails * @run main/othervm/java.security.policy=SerialOld.policy SerialOld */ import java.io.*; -import java.security.*; public class SerialOld { public static void main(String[] args) throws Exception { @@ -40,10 +39,15 @@ deserializeTigerKey("DSA"); deserializeTigerKey("RSA"); - // verify pre-tiger keys still deserialize in our VM + // verify pre-tiger keys still deserialize in our VM. + + // There used to be a RSA test here, but the serialized file contained + // classes introduced in JDK 5.0 (sun.security.rsa.RSA*). The older + // RSA keys from JDK 1.4.2 were of class JSA_* which were removed when + // sun.security.rsa was introduced. (See JDK-8301126 for more + // details.) The test/data has been removed. deserializeKey("DSA"); - deserializeKey("RSA"); deserializeKey("DH"); deserializeKey("AES"); deserializeKey("Blowfish"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java openjdk-lts-11.0.21+9/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/MessageDigest/ThreadSafetyTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Azul Systems, Inc. All rights reserved. + * Copyright (c) 2020, 2021, Azul Systems, 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 @@ -23,9 +23,9 @@ /* * @test - * @bug 8241960 + * @bug 8241960 8277353 * @summary Confirm that java.security.MessageDigest is thread-safe after clone. - * @run main/othervm ThreadSafetyTest 5 4 + * @run main ThreadSafetyTest 4 2 */ import java.security.MessageDigest; @@ -56,7 +56,7 @@ duration = Integer.parseInt(args[1]); } int nProcessors = Runtime.getRuntime().availableProcessors(); - int nTasks = nProcessors * threadsFactor; + int nTasks = Math.min(nProcessors, 4) * threadsFactor; System.out.println("Testing with " + nTasks + " threads on " + nProcessors + " processors for " + duration + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/misc/TestDefaultRandom.java openjdk-lts-11.0.21+9/test/jdk/java/security/misc/TestDefaultRandom.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/misc/TestDefaultRandom.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/misc/TestDefaultRandom.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,229 @@ +/* + * 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. + */ + +/** + * @test + * @bug 8260274 + * @run main/othervm TestDefaultRandom APG 1 + * @run main/othervm TestDefaultRandom APG 2 + * @run main/othervm TestDefaultRandom KPG 1 + * @run main/othervm TestDefaultRandom KPG 2 + * @run main/othervm TestDefaultRandom CIP 1 + * @run main/othervm TestDefaultRandom CIP 2 + * @run main/othervm TestDefaultRandom CIP 3 + * @run main/othervm TestDefaultRandom CIP 4 + * @run main/othervm TestDefaultRandom KA 1 + * @run main/othervm TestDefaultRandom KA 2 + * @run main/othervm TestDefaultRandom KG 1 + * @run main/othervm TestDefaultRandom KG 2 + * @summary Ensure the default SecureRandom impl is used as the javadoc + * spec stated when none supplied. + */ +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Map; +import java.security.*; +import java.security.cert.Certificate; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAGenParameterSpec; +import java.security.spec.RSAKeyGenParameterSpec; +import javax.crypto.Cipher; +import javax.crypto.KeyAgreement; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import javax.crypto.spec.IvParameterSpec; + +public class TestDefaultRandom { + + public static void main(String[] argv) throws Exception { + if (argv.length != 2) { + throw new RuntimeException("Error: missing test parameters"); + } + + switch (argv[0]) { + case "APG": + check(AlgorithmParameterGenerator.getInstance("DSA"), argv[1]); + break; + case "KPG": + check(KeyPairGenerator.getInstance("RSA"), argv[1]); + break; + case "CIP": + check(Cipher.getInstance("AES/CBC/NoPadding"), argv[1]); + break; + case "KA": + check(KeyAgreement.getInstance("DH"), argv[1]); + break; + case "KG": + check(KeyGenerator.getInstance("AES"), argv[1]); + break; + default: + throw new RuntimeException("Error: unsupported test type"); + } + } + + private static void check(Object obj, String testNum) { + if (obj == null) throw new NullPointerException(); + + SampleProvider prov = new SampleProvider(); + Security.insertProviderAt(prov, 1); + + int b4Cnt = SampleProvider.count; + + System.out.println("before, count = " + b4Cnt); + // Note that the arguments may not be valid, they just need to be + // non-null to trigger the call for checking if the default + // SecureRandom impl is used + try { + if (obj instanceof AlgorithmParameterGenerator) { + AlgorithmParameterGenerator apg = + (AlgorithmParameterGenerator) obj; + switch (testNum) { + case "1": + apg.init(123); + break; + case "2": + apg.init((AlgorithmParameterSpec) null); + break; + default: + throw new RuntimeException("Error: invalid test#"); + } + } else if (obj instanceof KeyPairGenerator) { + KeyPairGenerator kpg = (KeyPairGenerator) obj; + switch (testNum) { + case "1": + kpg.initialize(123); + break; + case "2": + kpg.initialize((AlgorithmParameterSpec) null); + break; + default: + throw new RuntimeException("Error: invalid test#"); + } + } else if (obj instanceof Cipher) { + Cipher c = (Cipher) obj; + switch (testNum) { + case "1": + c.init(Cipher.ENCRYPT_MODE, (Key) null); + break; + case "2": + c.init(Cipher.ENCRYPT_MODE, (Key) null, + (AlgorithmParameterSpec) null); + break; + case "3": + c.init(Cipher.ENCRYPT_MODE, (Key) null, + (AlgorithmParameters) null); + break; + case "4": + c.init(Cipher.ENCRYPT_MODE, (Certificate)null); + break; + default: + throw new RuntimeException("Error: invalid test#"); + } + } else if (obj instanceof KeyAgreement) { + KeyAgreement ka = (KeyAgreement) obj; + switch (testNum) { + case "1": + ka.init((Key) null); + break; + case "2": + ka.init((Key) null, (AlgorithmParameterSpec) null); + break; + default: + throw new RuntimeException("Error: invalid test#"); + } + } else if (obj instanceof KeyGenerator) { + KeyGenerator kg = (KeyGenerator) obj; + switch (testNum) { + case "1": + kg.init(123); + break; + case "2": + kg.init((AlgorithmParameterSpec) null); + break; + default: + throw new RuntimeException("Error: invalid test#"); + } + } else { + throw new RuntimeException("Error: Unsupported type"); + } + } catch (GeneralSecurityException | InvalidParameterException e) { + // expected; ignore + } + System.out.println("after, count = " + SampleProvider.count); + if (SampleProvider.count == b4Cnt) { + throw new RuntimeException("Test Failed"); + } + } + + private static class SampleProvider extends Provider { + + static int count = 0; + static String SR_ALGO = "Custom"; + + SampleProvider() { + super("Sample", "1.0", "test provider with custom SR impl"); + putService(new SampleService(this, "SecureRandom", SR_ALGO, + "SampleSecureRandom.class" /* stub class name */, + null, null)); + } + + private static class SampleService extends Service { + + SampleService(Provider p, String type, String alg, String cn, + List aliases, Map attrs) { + super(p, type, alg, cn, aliases, attrs); + } + + @Override + public Object newInstance(Object param) + throws NoSuchAlgorithmException { + String alg = getAlgorithm(); + String type = getType(); + + if (type.equals("SecureRandom") && alg.equals(SR_ALGO)) { + SampleProvider.count++; + return new CustomSR(); + } else { + // should never happen + throw new NoSuchAlgorithmException("No support for " + alg); + } + } + } + + private static class CustomSR extends SecureRandomSpi { + @Override + protected void engineSetSeed(byte[] seed) { + } + + @Override + protected void engineNextBytes(byte[] bytes) { + } + + @Override + protected byte[] engineGenerateSeed(int numBytes) { + return new byte[numBytes]; + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/Security/ConfigFileTest.java openjdk-lts-11.0.21+9/test/jdk/java/security/Security/ConfigFileTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/Security/ConfigFileTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/Security/ConfigFileTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,122 @@ +/* + * 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 jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.*; + +import java.security.Provider; +import java.security.Security; +import java.util.Arrays; +import java.util.Optional; + +/* + * @test + * @summary Throw error if default java.security file is missing + * @bug 8155246 8292297 + * @library /test/lib + * @run main ConfigFileTest + */ +public class ConfigFileTest { + + public static void main(String[] args) throws Exception { + Path copyJdkDir = Path.of("./jdk-8155246-tmpdir"); + Path copiedJava = Optional.of( + Path.of(copyJdkDir.toString(), "bin", "java")) + .orElseThrow(() -> new RuntimeException("Unable to locate new JDK") + ); + + if (args.length == 1) { + // set up is complete. Run code to exercise loading of java.security + Provider[] provs = Security.getProviders(); + System.out.println(Arrays.toString(provs) + "NumProviders: " + provs.length); + } else { + Files.createDirectory(copyJdkDir); + Path jdkTestDir = Path.of(Optional.of(System.getProperty("test.jdk")) + .orElseThrow(() -> new RuntimeException("Couldn't load JDK Test Dir")) + ); + + copyJDK(jdkTestDir, copyJdkDir); + String extraPropsFile = Path.of(System.getProperty("test.src"), "override.props").toString(); + + // exercise some debug flags while we're here + // regular JDK install - should expect success + exerciseSecurity(0, "java", + copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-Djavax.net.debug=all", "ConfigFileTest", "runner"); + + // given an overriding security conf file that doesn't exist, we shouldn't + // overwrite the properties from original/master security conf file + exerciseSecurity(0, "SUN version", + copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-Djavax.net.debug=all", + "-Djava.security.properties==file:///" + extraPropsFile + "badFileName", + "ConfigFileTest", "runner"); + + // test JDK launch with customized properties file + exerciseSecurity(0, "NumProviders: 6", + copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-Djavax.net.debug=all", + "-Djava.security.properties==file:///" + extraPropsFile, + "ConfigFileTest", "runner"); + + // delete the master conf file + Files.delete(Path.of(copyJdkDir.toString(), "conf", + "security","java.security")); + + // launch JDK without java.security file being present or specified + exerciseSecurity(1, "Error loading java.security file", + copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-Djavax.net.debug=all", + "ConfigFileTest", "runner"); + + // test the override functionality also. Should not be allowed since + // "security.overridePropertiesFile=true" Security property is missing. + exerciseSecurity(1, "Error loading java.security file", + copiedJava.toString(), "-cp", System.getProperty("test.classes"), + "-Djava.security.debug=all", "-Djavax.net.debug=all", + "-Djava.security.properties==file:///" + extraPropsFile, "ConfigFileTest", "runner"); + } + } + + private static void exerciseSecurity(int exitCode, String output, String... args) throws Exception { + ProcessBuilder process = new ProcessBuilder(args); + OutputAnalyzer oa = ProcessTools.executeProcess(process); + oa.shouldHaveExitValue(exitCode).shouldContain(output); + } + + private static void copyJDK(Path src, Path dst) throws Exception { + Files.walk(src) + .skip(1) + .forEach(file -> { + try { + Files.copy(file, dst.resolve(src.relativize(file)), StandardCopyOption.COPY_ATTRIBUTES); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + }); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/Security/override.props openjdk-lts-11.0.21+9/test/jdk/java/security/Security/override.props --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/Security/override.props 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/Security/override.props 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,7 @@ +# exercise ServiceLoader and legacy (class load) approach +security.provider.1=sun.security.provider.Sun +security.provider.2=SunRsaSign +security.provider.3=SunJSSE +security.provider.4=com.sun.crypto.provider.SunJCE +security.provider.5=SunJGSS +security.provider.6=SunSASL \ No newline at end of file diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/testlibrary/CertificateBuilder.java openjdk-lts-11.0.21+9/test/jdk/java/security/testlibrary/CertificateBuilder.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/testlibrary/CertificateBuilder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/testlibrary/CertificateBuilder.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -322,7 +322,7 @@ if (!ekuOids.isEmpty()) { Vector oidVector = new Vector<>(); for (String oid : ekuOids) { - oidVector.add(new ObjectIdentifier(oid)); + oidVector.add(ObjectIdentifier.of(oid)); } addExtension(new ExtendedKeyUsageExtension(oidVector)); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/security/testlibrary/SimpleOCSPServer.java openjdk-lts-11.0.21+9/test/jdk/java/security/testlibrary/SimpleOCSPServer.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/security/testlibrary/SimpleOCSPServer.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/security/testlibrary/SimpleOCSPServer.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -45,11 +45,7 @@ import sun.security.provider.certpath.CertId; import sun.security.provider.certpath.OCSPResponse; import sun.security.provider.certpath.OCSPResponse.ResponseStatus; -import sun.security.util.Debug; -import sun.security.util.DerInputStream; -import sun.security.util.DerOutputStream; -import sun.security.util.DerValue; -import sun.security.util.ObjectIdentifier; +import sun.security.util.*; /** @@ -59,8 +55,8 @@ public class SimpleOCSPServer { private final Debug debug = Debug.getInstance("oserv"); private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID = - ObjectIdentifier.newInternal( - new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 1}); + ObjectIdentifier.of(KnownOIDs.OCSPBasicResponse); + private static final SimpleDateFormat utcDateFmt = new SimpleDateFormat("MMM dd yyyy, HH:mm:ss z"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java openjdk-lts-11.0.21+9/test/jdk/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -614,7 +614,7 @@ @Test(dataProvider = "parseGenericTimeZonePatterns") public void test_appendZoneText_parseGenericTimeZonePatterns(String pattern, LocalDateTime ldt, ZoneId zId, String input) { - DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(); + DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(Locale.US); ZonedDateTime expected = ZonedDateTime.parse(input, df); ZonedDateTime actual = ZonedDateTime.of(ldt, zId); assertEquals(actual, expected); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/util/concurrent/CompletableFuture/LostInterrupt.java openjdk-lts-11.0.21+9/test/jdk/java/util/concurrent/CompletableFuture/LostInterrupt.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/util/concurrent/CompletableFuture/LostInterrupt.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/util/concurrent/CompletableFuture/LostInterrupt.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 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. + */ + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ThreadLocalRandom; +import static java.util.concurrent.TimeUnit.DAYS; + +/* + * @test + * @bug 8254350 + * @run main LostInterrupt + * @summary CompletableFuture.get may swallow interrupt status + * @key randomness + */ + +// TODO: Rewrite as a CompletableFuture tck test ? + +/** + * Submits a task that completes immediately, then invokes CompletableFuture.get + * with the interrupt status set. CompletableFuture.get should either complete + * immediately with the interrupt status set, or else throw InterruptedException + * with the interrupt status cleared. + */ +public class LostInterrupt { + static final int ITERATIONS = 10_000; + + public static void main(String[] args) throws Exception { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + ForkJoinPool executor = new ForkJoinPool(1); + try { + for (int i = 0; i < ITERATIONS; i++) { + CompletableFuture future = new CompletableFuture<>(); + boolean timed = rnd.nextBoolean(); + executor.execute(() -> future.complete("foo")); + + Thread.currentThread().interrupt(); + try { + String result = timed ? future.get(1, DAYS) : future.get(); + + if (!Thread.interrupted()) + throw new AssertionError("lost interrupt, run=" + i); + } catch (InterruptedException expected) { + if (Thread.interrupted()) + throw new AssertionError( + "interrupt status not cleared, run=" + i); + } + } + } finally { + executor.shutdown(); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/util/concurrent/CompletableFuture/SwallowedInterruptedException.java openjdk-lts-11.0.21+9/test/jdk/java/util/concurrent/CompletableFuture/SwallowedInterruptedException.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/util/concurrent/CompletableFuture/SwallowedInterruptedException.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/util/concurrent/CompletableFuture/SwallowedInterruptedException.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 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. + */ + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadLocalRandom; +import static java.util.concurrent.TimeUnit.DAYS; +import java.util.concurrent.atomic.AtomicReference; + +/* + * @test + * @bug 8254350 + * @run main SwallowedInterruptedException + * @key randomness + */ + +// TODO: incorporate into CompletableFuture tck tests + +public class SwallowedInterruptedException { + static final int ITERATIONS = 100; + + public static void main(String[] args) throws Throwable { + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + for (int i = 1; i <= ITERATIONS; i++) { + boolean timed = rnd.nextBoolean(); + long sleepMillis = rnd.nextLong(10); + + CompletableFuture future = new CompletableFuture<>(); + CountDownLatch threadRunning = new CountDownLatch(1); + AtomicReference fail = new AtomicReference<>(); + + Thread thread = new Thread(() -> { + threadRunning.countDown(); + + try { + Void result = (timed) ? future.get(1, DAYS) : future.get(); + + if (!Thread.currentThread().isInterrupted()) { + fail.set(new AssertionError( + "Future.get completed with interrupt status not set")); + } + } catch (InterruptedException ex) { + if (Thread.currentThread().isInterrupted()) { + fail.set(new AssertionError( + "InterruptedException with interrupt status set")); + } + } catch (Throwable ex) { + fail.set(ex); + } + }); + thread.start(); + threadRunning.await(); + + // interrupt thread, then set result after an optional (random) delay + thread.interrupt(); + if (sleepMillis > 0) + Thread.sleep(sleepMillis); + future.complete(null); + + thread.join(); + if (fail.get() != null) { + throw new AssertionError( + String.format("Test failed at iteration %d with [timed=%s sleepMillis=%d]", + i, timed, sleepMillis), + fail.get()); + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/java/util/RandomAccess/Basic.java openjdk-lts-11.0.21+9/test/jdk/java/util/RandomAccess/Basic.java --- openjdk-lts-11.0.20.1+1/test/jdk/java/util/RandomAccess/Basic.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/java/util/RandomAccess/Basic.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -21,111 +21,148 @@ * questions. */ -/* +/** * @test - * @bug 4327164 + * @bug 4327164 8229338 * @summary Basic test for new RandomAccess interface + * @run testng Basic */ -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Random; -import java.util.RandomAccess; -import java.util.Vector; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; +import java.util.function.Supplier; public class Basic { - public static void main(String[] args) throws Exception { - List a0 = Arrays.asList(new String[] { "a", "b", "c" }); - List a[] = { a0, new ArrayList(a0), new LinkedList(a0), - new Vector(a0) }; - - if (!(a[0] instanceof RandomAccess)) - throw new Exception("Arrays.asList doesn't implement RandomAccess"); - if (!(a[1] instanceof RandomAccess)) - throw new Exception("ArrayList doesn't implement RandomAccess"); - if (a[2] instanceof RandomAccess) - throw new Exception("LinkedList implements RandomAccess"); - if (!(a[3] instanceof RandomAccess)) - throw new Exception("Vector doesn't implement RandomAccess"); - - for (int i = 0; i < a.length; i++) { - List t = a[i]; - List ut = Collections.unmodifiableList(t); - List st = Collections.synchronizedList(t); - - boolean random = t instanceof RandomAccess; - if ((ut instanceof RandomAccess) != random) - throw new Exception( - "Unmodifiable fails to preserve RandomAccess: " + i); - if ((st instanceof RandomAccess) != random) - throw new Exception( - "Synchronized fails to preserve RandomAccess: " + i); - - while (t.size() > 0) { - t = t.subList(0, t.size() - 1); - if ((t instanceof RandomAccess) != random) - throw new Exception( - "SubList fails to preserve RandomAccess: " + i - + ", " + t.size()); - - ut = ut.subList(0, ut.size() - 1); - if ((ut instanceof RandomAccess) != random) - throw new Exception( - "SubList(unmodifiable) fails to preserve RandomAccess: " - + i + ", " + ut.size()); - - st = st.subList(0, st.size() - 1); - if ((st instanceof RandomAccess) != random) - throw new Exception( - "SubList(synchronized) fails to preserve RandomAccess: " - + i + ", " + st.size()); - } - } - - // Test that shuffle works the same on random and sequential access - List al = new ArrayList(); - for (int j = 0; j < 100; j++) - al.add(Integer.valueOf(2 * j)); - List ll = new LinkedList(al); - Random r1 = new Random(666), r2 = new Random(666); + + /* + * Lists which implement Random Access interface + */ + @DataProvider(name = "testLists") + public Object[][] testData() { + var intArray = new Integer[100]; + var stack = new Stack<>(); + var random = new Random(); for (int i = 0; i < 100; i++) { - Collections.shuffle(al, r1); - Collections.shuffle(ll, r2); - if (!al.equals(ll)) - throw new Exception("Shuffle failed: " + i); + var r = random.nextInt(100); + stack.push(r); + intArray[i] = r; } + List list = Arrays.asList(intArray); + return new Object[][]{ + {list, true, "Arrays.asList"}, + {stack, true, "Stack"}, + {new ArrayList<>(list), true, "ArrayList"}, + {new LinkedList<>(list), false, "LinkedList"}, + {new Vector<>(list), true, "Vector"}, + {new CopyOnWriteArrayList<>(list), true, "CopyOnWriteArrayList"} + }; + } + + @Test(dataProvider = "testLists") + public void testRandomAccess(List list, boolean expectedRA, String failMsg) { - // Test that fill works on random & sequential access - List gumbyParade = Collections.nCopies(100, "gumby"); - Collections.fill(al, "gumby"); - if (!al.equals(gumbyParade)) - throw new Exception("ArrayList fill failed"); - Collections.fill(ll, "gumby"); - if (!ll.equals(gumbyParade)) - throw new Exception("LinkedList fill failed"); + var actualRA = list instanceof RandomAccess; + assertEquals(actualRA, expectedRA, failMsg); + List unmodList = Collections.unmodifiableList(list); + List syncList = Collections.synchronizedList(list); + assertEquals((unmodList instanceof RandomAccess), actualRA, + "Unmodifiable fails to preserve RandomAccess"); + assertEquals((syncList instanceof RandomAccess), actualRA, + "Synchronized fails to preserve RandomAccess"); + + while (list.size() > 0) { + list = list.subList(0, list.size() - 1); + assertEquals((list instanceof RandomAccess), actualRA, + "SubList fails to preserve RandomAccess: " + list.size()); + + unmodList = unmodList.subList(0, unmodList.size() - 1); + assertEquals((unmodList instanceof RandomAccess), actualRA, + "SubList(unmodifiable) fails to preserve RandomAccess: " + + unmodList.size()); + + syncList = syncList.subList(0, syncList.size() - 1); + assertEquals((syncList instanceof RandomAccess), actualRA, + "SubList(synchronized) fails to preserve RandomAccess: " + + syncList.size()); + } + } + + @Test(dataProvider = "testLists") + public void testListCopy(List list, boolean expectedRA, String failMsg) { + ArrayList testCollection = new ArrayList<>(Collections.nCopies(100, 0)); + // Test that copy works on random & sequential access + Collections.copy(list, testCollection); + assertEquals(list, testCollection, "Copy failed: " + failMsg); + } + + @Test(dataProvider = "testLists") + public void testListFill(List list, boolean expectedRA, String failMsg) { + ArrayList testCollection = new ArrayList<>(Collections.nCopies(100, 0)); // Test that copy works on random & sequential access - List pokeyParade = Collections.nCopies(100, "pokey"); - Collections.copy(al, pokeyParade); - if (!al.equals(pokeyParade)) - throw new Exception("ArrayList copy failed"); - Collections.copy(ll, pokeyParade); - if (!ll.equals(pokeyParade)) - throw new Exception("LinkedList copy failed"); - - // Test that binarySearch works the same on random & sequential access - al = new ArrayList(); - for (int i = 0; i < 10000; i++) - al.add(Integer.valueOf(2 * i)); - ll = new LinkedList(al); + Collections.fill(list, 0); + assertEquals(list, testCollection, "Fill failed: " + failMsg); + } + + /* + * Test that shuffle and binarySearch work the same on random and sequential access lists. + */ + @DataProvider(name = "testFactoryLists") + public Object[][] testDataFactory() { + return new Object[][]{ + {"ArrayList -> LinkedList", supplier(ArrayList::new), copyCtor(LinkedList::new)}, + {"CopyOnWriteArrayList -> Stack", supplier(CopyOnWriteArrayList::new), + copyCtor((list) -> { var s = new Stack();s.addAll(list);return s; })} + }; + } + + private Supplier> supplier(Supplier> supplier) { + return supplier; + } + + private Function, List> copyCtor(Function, List> ctor) { + return ctor; + } + + @Test(dataProvider = "testFactoryLists") + public void testListShuffle(String description, Supplier> randomAccessListSupplier, + Function, List> otherListFactory) { + + //e.g: ArrayList al = new ArrayList<>(); + List l1 = randomAccessListSupplier.get(); + for (int j = 0; j < 100; j++) { + l1.add(Integer.valueOf(2 * j)); + } + // e.g: List ll = new LinkedList<>(al); + List l2 = otherListFactory.apply(l1); + for (int i = 0; i < 100; i++) { + Collections.shuffle(l1, new Random(666)); + Collections.shuffle(l2, new Random(666)); + assertEquals(l1, l2, "Shuffle failed: " + description); + } + } + + @Test(dataProvider = "testFactoryLists") + public void testListBinarySearch(String description, Supplier> randomAccessListSupplier, + Function, List> otherListFactory) { + + //e.g: ArrayList al = new ArrayList<>(); + List l1 = randomAccessListSupplier.get(); + for (int i = 0; i < 10000; i++) { + l1.add(Integer.valueOf(2 * i)); + } + // e.g: List ll = new LinkedList<>(al); + List l2 = otherListFactory.apply(l1); for (int i = 0; i < 500; i++) { - Integer key = Integer.valueOf(r1.nextInt(20000)); - if (Collections.binarySearch(al, key) != Collections - .binarySearch(ll, key)) - throw new Exception("Binary search failed: " + i); + Integer key = Integer.valueOf(new Random(666).nextInt(20000)); + assertEquals(Collections.binarySearch(l1, key), Collections + .binarySearch(l2, key), "Binary search failed: " + description); } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/accessibility/MaximumAccessibleValueTest.java openjdk-lts-11.0.21+9/test/jdk/javax/accessibility/MaximumAccessibleValueTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/accessibility/MaximumAccessibleValueTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/accessibility/MaximumAccessibleValueTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,71 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4422362 + * @summary Wrong Max Accessible Value with BoundedRangeModel components + * @run main MaximumAccessibleValueTest + */ + +import javax.swing.JProgressBar; +import javax.swing.JScrollBar; +import javax.swing.JSlider; +import javax.swing.SwingUtilities; + +public class MaximumAccessibleValueTest { + + public static void doTest() { + + JScrollBar jScrollBar = new JScrollBar(); + JProgressBar jProgressBar = new JProgressBar(); + JSlider jSlider = new JSlider(); + + if (((Integer) jScrollBar.getAccessibleContext().getAccessibleValue() + .getMaximumAccessibleValue()).intValue() != jScrollBar.getMaximum() + - jScrollBar.getVisibleAmount()) { + throw new RuntimeException( + "Wrong MaximumAccessibleValue returned by JScrollBar"); + } + + if (((Integer) jProgressBar.getAccessibleContext().getAccessibleValue() + .getMaximumAccessibleValue().intValue()) != (jProgressBar + .getMaximum() - jProgressBar.getModel().getExtent())) { + throw new RuntimeException( + "Wrong MaximumAccessibleValue returned by JProgressBar"); + } + + if (((Integer) jSlider.getAccessibleContext().getAccessibleValue() + .getMaximumAccessibleValue()).intValue() != jSlider.getMaximum() + - jSlider.getModel().getExtent()) { + throw new RuntimeException( + "Wrong MaximumAccessibleValue returned by JSlider"); + } + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> doTest()); + System.out.println("Test Passed"); + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/accessibility/SetCurrentAccessibleValueTest.java openjdk-lts-11.0.21+9/test/jdk/javax/accessibility/SetCurrentAccessibleValueTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/accessibility/SetCurrentAccessibleValueTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/accessibility/SetCurrentAccessibleValueTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,76 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4422535 + * @summary setCurrentAccessibleValue returns true only for an Integer + * @run main SetCurrentAccessibleValueTest + */ + +import java.math.BigDecimal; +import java.math.BigInteger; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JInternalFrame; +import javax.swing.JProgressBar; +import javax.swing.JScrollBar; +import javax.swing.JSlider; +import javax.swing.JSplitPane; +import javax.swing.SwingUtilities; + +public class SetCurrentAccessibleValueTest { + + public static void doTest() { + JComponent[] jComponents = + { new JButton(), new JInternalFrame(), new JSplitPane(), + new JScrollBar(), new JProgressBar(), new JSlider() }; + + for (JComponent jComponent : jComponents) { + testIt(jComponent, (Float.valueOf(5))); + testIt(jComponent, (Double.valueOf(37.266))); + testIt(jComponent, (Integer.valueOf(10))); + testIt(jComponent, (Long.valueOf(123L))); + testIt(jComponent, (Short.valueOf((short) 123))); + testIt(jComponent, (BigInteger.ONE)); + testIt(jComponent, (new BigDecimal(BigInteger.ONE))); + } + + } + + static void testIt(JComponent jComponent, Number number) { + if (!jComponent.getAccessibleContext().getAccessibleValue() + .setCurrentAccessibleValue(number)) { + throw new RuntimeException(jComponent.getClass().getName() + + " Accessible Value implementation doesn't accept " + + number.getClass().getName()); + } + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(() -> doTest()); + System.out.println("Test Passed"); + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/crypto/SecretKeyFactory/security.properties openjdk-lts-11.0.21+9/test/jdk/javax/crypto/SecretKeyFactory/security.properties --- openjdk-lts-11.0.20.1+1/test/jdk/javax/crypto/SecretKeyFactory/security.properties 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/crypto/SecretKeyFactory/security.properties 2023-10-06 05:33:33.000000000 +0000 @@ -1,6 +1,3 @@ -# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. -# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - jdk.security.provider.preferred= jdk.jar.disabledAlgorithms= diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/print/attribute/SidesAttributeTest.java openjdk-lts-11.0.21+9/test/jdk/javax/print/attribute/SidesAttributeTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/print/attribute/SidesAttributeTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/print/attribute/SidesAttributeTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, BELLSOFT. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 JDK-8311033 + * @summary [macos] PrinterJob does not take into account Sides attribute + * @run main/manual SidesAttributeTest + */ + +import javax.print.PrintService; +import javax.print.attribute.Attribute; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.Sides; +import javax.swing.*; +import java.awt.*; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class SidesAttributeTest { + + private static final long TIMEOUT = 10 * 60_000; + private static volatile boolean testPassed = true; + private static volatile boolean testFinished = false; + private static volatile boolean timeout = false; + + private static volatile int testCount; + private static volatile int testTotalCount; + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeLater(() -> { + + Set supportedSides = getSupportedSidesAttributes(); + if (supportedSides.size() > 1) { + testTotalCount = supportedSides.size(); + testPrint(Sides.ONE_SIDED, supportedSides); + testPrint(Sides.DUPLEX, supportedSides); + testPrint(Sides.TUMBLE, supportedSides); + } + testFinished = true; + }); + + long time = System.currentTimeMillis() + TIMEOUT; + + while (System.currentTimeMillis() < time) { + if (!testPassed || testFinished) { + break; + } + Thread.sleep(500); + } + + timeout = true; + + closeDialogs(); + + if (!testPassed) { + throw new Exception("Test failed!"); + } + + if (testCount != testTotalCount) { + throw new Exception( + "Timeout: " + testCount + " tests passed out from " + testTotalCount); + } + } + + private static void print(Sides sides) throws PrinterException { + PrintRequestAttributeSet attr = new HashPrintRequestAttributeSet(); + attr.add(sides); + + for (Attribute attribute : attr.toArray()) { + System.out.printf("Used print request attribute: %s%n", attribute); + } + + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(new SidesAttributePrintable(sides)); + + job.print(attr); + } + + private static class SidesAttributePrintable implements Printable { + + private final Sides sidesAttr; + + public SidesAttributePrintable(Sides sidesAttr) { + this.sidesAttr = sidesAttr; + } + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + + if (pageIndex >= 2) { + return NO_SUCH_PAGE; + } + + int x = (int) (pageFormat.getImageableX() + pageFormat.getImageableWidth() / 10); + int y = (int) (pageFormat.getImageableY() + pageFormat.getImageableHeight() / 5); + + Graphics2D g = (Graphics2D) graphics; + String text = getPageText(sidesAttr, pageIndex + 1); + g.drawString(text, x, y); + return PAGE_EXISTS; + } + } + + private static String getPageText(Sides sides, int page) { + return String.format("Page: %d - %s", page, getSidesText(sides)); + } + + private static String getSidesText(Sides sides) { + if (Sides.ONE_SIDED.equals(sides)) { + return "ONE_SIDED"; + } else if (Sides.TWO_SIDED_SHORT_EDGE.equals(sides)) { + return "TWO_SIDED_SHORT_EDGE (TUMBLE)"; + } else if (Sides.TWO_SIDED_LONG_EDGE.equals(sides)) { + return "TWO_SIDED_LONG_EDGE (DUPLEX)"; + } + throw new RuntimeException("Unknown sides attribute: " + sides); + } + + private static String getSidesDescription(Sides sides) { + if (Sides.ONE_SIDED.equals(sides)) { + return "a one-sided document"; + } else if (Sides.TWO_SIDED_SHORT_EDGE.equals(sides)) { + return "double-sided document along the short edge of the paper"; + } else if (Sides.TWO_SIDED_LONG_EDGE.equals(sides)) { + return "double-sided document along the long edge of the paper"; + } + throw new RuntimeException("Unknown sides attribute: " + sides); + } + + private static Set getSupportedSidesAttributes() { + Set supportedSides = new HashSet<>(); + + PrinterJob printerJob = PrinterJob.getPrinterJob(); + PrintService service = printerJob.getPrintService(); + + Object obj = service.getSupportedAttributeValues(Sides.class, null, null); + if (obj instanceof Attribute[]) { + Attribute[] attr = (Attribute[]) obj; + Collections.addAll(supportedSides, attr); + } + + return supportedSides; + } + + private static void pass() { + testCount++; + } + + private static void fail(Sides sides) { + System.out.printf("Failed test: %s%n", getSidesText(sides)); + testPassed = false; + } + + private static void runPrint(Sides sides) { + try { + print(sides); + } catch (PrinterException e) { + fail(sides); + e.printStackTrace(); + } + } + + private static void testPrint(Sides sides, Set supportedSides) { + + if (!supportedSides.contains(sides) || !testPassed || timeout) { + return; + } + + String[] instructions = { + "Up to " + testTotalCount + " tests will run and it will test all the cases", + "supported by the printer.", + "", + "The test is " + (testCount + 1) + " from " + testTotalCount + ".", + "", + "On-screen inspection is not possible for this printing-specific", + "test therefore its only output is two printed pages (one or two sided).", + "To be able to run this test it is required to have a default", + "printer configured in your user environment.", + "", + "Visual inspection of the printed pages is needed.", + "A passing test will print 2 pages:", + " - the first page with the text: " + getPageText(sides, 1), + " - the second page with the text: " + getPageText(sides, 2), + "", + "The test fails if the pages are not printed according to the tested", + getSidesText(sides) + " attribute where " + getSidesDescription(sides), + "needs to be printed.", + "", + }; + + String title = String.format("Print %s sides test: %d from %d", + getSidesText(sides), testCount + 1, testTotalCount); + final JDialog dialog = new JDialog((Frame) null, title, Dialog.ModalityType.DOCUMENT_MODAL); + JTextArea textArea = new JTextArea(String.join("\n", instructions)); + textArea.setEditable(false); + final JButton testButton = new JButton("Start Test"); + final JButton passButton = new JButton("PASS"); + passButton.setEnabled(false); + passButton.addActionListener((e) -> { + pass(); + dialog.dispose(); + }); + final JButton failButton = new JButton("FAIL"); + failButton.setEnabled(false); + failButton.addActionListener((e) -> { + fail(sides); + dialog.dispose(); + }); + testButton.addActionListener((e) -> { + testButton.setEnabled(false); + runPrint(sides); + passButton.setEnabled(true); + failButton.setEnabled(true); + }); + + JPanel mainPanel = new JPanel(new BorderLayout()); + mainPanel.add(textArea, BorderLayout.CENTER); + JPanel buttonPanel = new JPanel(new FlowLayout()); + buttonPanel.add(testButton); + buttonPanel.add(passButton); + buttonPanel.add(failButton); + mainPanel.add(buttonPanel, BorderLayout.SOUTH); + dialog.add(mainPanel); + dialog.pack(); + dialog.setVisible(true); + dialog.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.out.println("Dialog closing"); + fail(sides); + } + }); + } + + private static void closeDialogs() { + for (Window w : Dialog.getWindows()) { + w.dispose(); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/security/auth/callback/Mutability.java openjdk-lts-11.0.21+9/test/jdk/javax/security/auth/callback/Mutability.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/security/auth/callback/Mutability.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/security/auth/callback/Mutability.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 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 + * @bug 8242330 + * @library /test/lib + * @summary Arrays should be cloned in several JAAS Callback classes + */ + +import javax.security.auth.callback.ChoiceCallback; +import javax.security.auth.callback.ConfirmationCallback; + +import static jdk.test.lib.Asserts.assertEQ; + +public class Mutability { + public static void main(String[] args) { + + // #1. ConfirmationCallback.new(3) + String[] i11 = {"1", "2"}; + ConfirmationCallback c1 = new ConfirmationCallback( + ConfirmationCallback.INFORMATION, + i11, + 0); + + // Modify argument of constructor + i11[0] = "x"; + String[] o11 = c1.getOptions(); + assertEQ(o11[0], "1"); + // Modify output + o11[0] = "y"; + String[] o12 = c1.getOptions(); + assertEQ(o12[0], "1"); + + // #2. ConfirmationCallback.new(4) + String[] i21 = {"1", "2"}; + ConfirmationCallback c2 = new ConfirmationCallback( + "Hi", + ConfirmationCallback.INFORMATION, + i21, + 0); + + // Modify argument of constructor + i21[0] = "x"; + assertEQ(c2.getOptions()[0], "1"); + + // #3. ChoiceCallback.new + String[] i31 = {"1", "2"}; + ChoiceCallback c3 = new ChoiceCallback( + "Hi", + i31, + 0, + true); + + // Modify argument of constructor + i31[0] = "x"; + String[] o31 = c3.getChoices(); + assertEQ(o31[0], "1"); + // Modify output of getChoices + o31[0] = "y"; + String[] o32 = c3.getChoices(); + assertEQ(o32[0], "1"); + + int[] s31 = {0, 1}; + c3.setSelectedIndexes(s31); + + // Modify argument of setSelectedIndexes + s31[0] = 1; + int[] s32 = c3.getSelectedIndexes(); + assertEQ(s32[0], 0); + // Modify output of getSelectedIndexes + s32[1] = 0; + int[] s33 = c3.getSelectedIndexes(); + assertEQ(s33[1], 1); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java openjdk-lts-11.0.21+9/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8284910 + * @summary Check that the cleaner is not bound to the PasswordCallback object + */ + +import javax.security.auth.callback.PasswordCallback; +import java.util.WeakHashMap; + +public final class CheckCleanerBound { + private final static WeakHashMap weakHashMap = + new WeakHashMap<>(); + + public static void main(String[] args) throws Exception { + // Create an object + PasswordCallback passwordCallback = + new PasswordCallback("Password: ", false); + passwordCallback.setPassword("ThisIsAPassword".toCharArray()); + + weakHashMap.put(passwordCallback, null); + passwordCallback = null; + + // Check if the PasswordCallback object could be collected. + // Wait to trigger the cleanup. + for (int i = 0; i < 10 && weakHashMap.size() != 0; i++) { + System.gc(); + } + + // Check if the object has been collected. The collection will not + // happen if the cleaner implementation in PasswordCallback is bound + // to the PasswordCallback object. + if (weakHashMap.size() > 0) { + throw new RuntimeException( + "PasswordCallback object is not released"); + } + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/security/auth/callback/PasswordCallback/PasswordCleanup.java openjdk-lts-11.0.21+9/test/jdk/javax/security/auth/callback/PasswordCallback/PasswordCleanup.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/security/auth/callback/PasswordCallback/PasswordCleanup.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/security/auth/callback/PasswordCallback/PasswordCleanup.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 8284910 + * @summary Check that PasswordCallback.clearPassword() clears the password + */ + +import javax.security.auth.callback.PasswordCallback; +import java.util.Arrays; + +public final class PasswordCleanup { + public static void main(String[] args) throws Exception { + // Create an object + PasswordCallback passwordCallback = + new PasswordCallback("Password: ", false); + passwordCallback.setPassword("ThisIsAPassword".toCharArray()); + char[] originPassword = passwordCallback.getPassword(); + + // Use password clear method. + passwordCallback.clearPassword(); + + // Check that the password is cleared. + char[] clearedPassword = passwordCallback.getPassword(); + if (Arrays.equals(originPassword, clearedPassword)) { + throw new RuntimeException( + "PasswordCallback.clearPassword() does not clear passwords"); + } + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/sound/sampled/Clip/SetPositionHang.java openjdk-lts-11.0.21+9/test/jdk/javax/sound/sampled/Clip/SetPositionHang.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/sound/sampled/Clip/SetPositionHang.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/sound/sampled/Clip/SetPositionHang.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,7 +28,7 @@ /** * @test - * @bug 8266421 + * @bug 8266421 8269091 * @summary Tests that Clip.setFramePosition/setMicrosecondPosition do not hang. */ public final class SetPositionHang implements Runnable { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4167850.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4167850.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4167850.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4167850.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * 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 4167850 + @summary Verify no exception removing items from an empty list. +*/ + +import javax.swing.JComboBox; + +public class bug4167850 { + + public static void main(String[] args) { + JComboBox comboBox = new JComboBox( + new Object[] { + "Coma Berenices", + "Triangulum", + "Camelopardis", + "Cassiopea"}); + + comboBox.removeAllItems(); + comboBox.removeAllItems(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4171464.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4171464.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4171464.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4171464.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * 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 4171464 + @summary JComboBox should not throw InternalError +*/ + +import javax.swing.ComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.event.ListDataListener; + +public class bug4171464 { + + public static void main(String args[]) { + ComboBoxModel model = new ComboBoxModel() { + public void setSelectedItem(Object anItem) {} + public Object getSelectedItem() {return null;} + public int getSize() {return 0;} + public Object getElementAt(int index) {return null;} + public void addListDataListener(ListDataListener l) {} + public void removeListDataListener(ListDataListener l) {} + }; + JComboBox comboBox = new JComboBox(); + comboBox.setModel(model); + try { + comboBox.addItem(new Object() {}); + } catch (InternalError e) { + // InternalError not suitable if app supplies non-mutable model. + throw new RuntimeException("4171464 TEST FAILED"); + } catch (Exception e) { + // Expected exception due to non-mutable model. + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4209474.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4209474.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4209474.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4209474.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * 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 4209474 + @summary setSelectedItem(int) should only fire events if selection changed - avoid recursive calls +*/ + +import javax.swing.JComboBox; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class bug4209474 { + + public static void main(String[] args) { + + JComboBox comboBox = new JComboBox( + new Object[] { + "Coma Berenices", + "Triangulum", + "Camelopardis", + "Cassiopea"}); + + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + comboBox.setSelectedIndex(0); + } + }; + + comboBox.addActionListener(listener); + comboBox.setSelectedIndex(0); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4234119.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4234119.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4234119.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4234119.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * 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 4234119 + @summary Tests if adding items to ComboBox is slow +*/ + +import javax.swing.JComboBox; + +public class bug4234119 { + + public static void main(String args[]) { + JComboBox jComboBox1 = new JComboBox(); + long startTime = System.currentTimeMillis(); + for (int i = 0 ; i < 500; i++) { + jComboBox1.addItem(Integer.valueOf(i)); + } + long deltaTime = System.currentTimeMillis() - startTime; + if (deltaTime > 20000) { + throw new Error("Test failed: adding items to ComboBox is SLOW! (it took " + deltaTime + " ms"); + } + System.out.println("Elapsed time: " + deltaTime); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4244614.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4244614.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4244614.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4244614.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. + */ + +/* + @test + @bug 4244614 + @summary Tests that JComboBox has setAction(Action) constructor +*/ + +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeListener; +import javax.swing.Action; +import javax.swing.JComboBox; + +public class bug4244614 { + +/** Auxiliary class implementing Action + */ + static class NullAction implements Action { + public void addPropertyChangeListener( + PropertyChangeListener listener) {} + public void removePropertyChangeListener( + PropertyChangeListener listener) {} + public void putValue(String key, Object value) {} + public void setEnabled(boolean b) {} + public void actionPerformed(ActionEvent e) {} + + public Object getValue(String key) { return null; } + public boolean isEnabled() { return false; } + } + + public static void main(String[] argv) { + Object[] comboData = {"First", "Second", "Third"}; + JComboBox combo = new JComboBox(comboData); + Action action = new NullAction(); + combo.setAction(action); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4276920.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4276920.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4276920.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4276920.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. + */ + +/* @test + @bug 4276920 + @summary Tests that BasicComboPopup.hide() doesn't cause unnecessary repaints + @key headful +*/ + +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4276920 { + + static volatile TestComboBox combo; + static volatile JFrame frame; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(bug4276920::createUI); + Thread.sleep(2000); + int before = combo.getRepaintCount(); + SwingUtilities.invokeAndWait(combo::hidePopup); + int after = combo.getRepaintCount(); + if (after > before) { + throw new Error("Failed 4276920: BasicComboPopup.hide() caused unnecessary repaint()"); + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + } + + static void createUI() { + combo = new TestComboBox(new String[] {"Why am I so slow?"}); + frame = new JFrame("bug4276920"); + frame.getContentPane().add(combo); + frame.pack(); + frame.validate(); + frame.setVisible(true); + } + + static class TestComboBox extends JComboBox { + int count = 0; + + TestComboBox(Object[] content) { + super(content); + } + + public void repaint() { + super.repaint(); + count++; + } + + int getRepaintCount() { + return count; + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4890345.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4890345.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4890345.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4890345.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,154 @@ +/* + * 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. + */ + +/* + @test + @bug 4890345 + @requires (os.family == "windows") + @summary 1.4.2 REGRESSION: JComboBox has problem in JTable in Windows L&F + @key headful +*/ + +import java.util.Vector; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.DefaultCellEditor; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; + +public class bug4890345 { + + volatile boolean passed = false; + volatile boolean isLafOk = true; + + volatile JFrame mainFrame; + volatile JTable tbl; + + public static void main(String[] args) throws Exception { + bug4890345 test = new bug4890345(); + try { + SwingUtilities.invokeAndWait(test::createUI); + if (!test.isLafOk) { + throw new RuntimeException("Could not create Win L&F"); + } + test.test(); + } finally { + JFrame f = test.mainFrame; + if (f != null) { + SwingUtilities.invokeAndWait(() -> f.dispose()); + } + } + } + + void createUI() { + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Exception ex) { + System.err.println("Can not initialize Windows L&F. Testing skipped."); + isLafOk = false; + } + + if (isLafOk) { + mainFrame = new JFrame("Bug4890345"); + String[] items = {"tt", "aa", "gg", "zz", "dd", "ll" }; + JComboBox comboBox = new JComboBox(items); + + tbl = new JTable(); + JScrollPane panel = new JScrollPane(tbl); + TableModel tm = createTableModel(); + tbl.setModel(tm); + tbl.setRowHeight(20); + tbl.getColumnModel().getColumn(1).setCellEditor( + new DefaultCellEditor(comboBox)); + + comboBox.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + passed = true; + } + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(panel, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + } + } + + public void test() throws Exception { + Robot robo = new Robot(); + robo.setAutoDelay(50); + robo.delay(1000); + tbl.editCellAt(0,0); + + robo.keyPress(KeyEvent.VK_TAB); + robo.keyRelease(KeyEvent.VK_TAB); + + robo.keyPress(KeyEvent.VK_TAB); + robo.keyRelease(KeyEvent.VK_TAB); + + robo.keyPress(KeyEvent.VK_F2); + robo.keyRelease(KeyEvent.VK_F2); + + robo.keyPress(KeyEvent.VK_DOWN); + robo.keyRelease(KeyEvent.VK_DOWN); + + robo.keyPress(KeyEvent.VK_ENTER); + robo.keyRelease(KeyEvent.VK_ENTER); + + robo.delay(1000); + + if (!passed) { + throw new RuntimeException("Popup was not shown after VK_DOWN press. Test failed."); + } + } + + private TableModel createTableModel() { + Vector hdr = new Vector(); + hdr.add("One"); + hdr.add("Two"); + Vector data = new Vector(); + Vector row = new Vector(); + row.add("tt"); + row.add("dd"); + data.add(row); + row = new Vector(); + row.add("ll"); + row.add("jj"); + data.add(row); + return new DefaultTableModel(data, hdr); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4924758.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4924758.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4924758.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4924758.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,115 @@ +/* + * 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. + */ + +/* @test + @bug 4924758 + @summary 1.4 REGRESSION: In Motif L&F JComboBox doesn't react when spacebar is pressed + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.PopupMenuListener; +import javax.swing.event.PopupMenuEvent; +import java.awt.event.KeyEvent; + +public class bug4924758 { + + static volatile boolean passed = false; + volatile boolean isLafOk = true; + + volatile JFrame mainFrame; + volatile JComboBox comboBox; + + public static void main(String[] args) throws Exception { + bug4924758 test = new bug4924758(); + try { + SwingUtilities.invokeAndWait(test::createUI); + if (!test.isLafOk) { + throw new RuntimeException("Could not create Win L&F"); + } + test.test(); + if (!passed) { + throw new RuntimeException( + "Popup was not closed after VK_SPACE press. Test failed."); + } + } finally { + JFrame f = test.mainFrame; + if (f != null) { + SwingUtilities.invokeAndWait(() -> f.dispose()); + } + } + } + + void createUI() { + 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; + return; + } + + mainFrame = new JFrame("Bug4924758"); + String[] items = {"One", "Two", "Three"}; + comboBox = new JComboBox(items); + comboBox.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + passed = true; + } + + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(comboBox, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.setVisible(true); + } + + void test() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(2000); + Point p = comboBox.getLocationOnScreen(); + Dimension size = comboBox.getSize(); + p.x += size.width / 2; + p.y += size.height / 2; + robot.mouseMove(p.x, p.y); + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + robot.keyPress(KeyEvent.VK_SPACE); + robot.keyRelease(KeyEvent.VK_SPACE); + robot.delay(2000); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4996503.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4996503.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug4996503.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug4996503.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,94 @@ +/* + * 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. + */ + +/* + @test + @bug 4996503 + @summary REGRESSION: NotSerializableException: javax.swing.plaf.basic.BasicComboPopup+1 + @key headful +*/ + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.event.InputEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; + +public class bug4996503 { + + static volatile JFrame frame = null; + static volatile JComboBox comboBox = null; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(() -> { + frame = new JFrame("bug4996503"); + String[] items = { "item0", "item1", "item2" }; + comboBox = new JComboBox(items); + frame.add(comboBox); + frame.pack(); + frame.validate(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoDelay(50); + robot.delay(1000); + Point p = comboBox.getLocationOnScreen(); + Dimension size = comboBox.getSize(); + p.x += size.width / 2; + p.y += size.height / 2; + robot.mouseMove(p.x, p.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + + ObjectOutputStream out = null; + + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + try { + out = new ObjectOutputStream(byteStream); + } catch (IOException e) {} + if (out != null) { + try { + out.writeObject(comboBox); + } catch (Exception e) { + System.out.println(e); + throw new Error("Serialization exception. Test failed."); + } + } + } finally { + if (frame != null) { + SwingUtilities.invokeAndWait(frame::dispose); + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug5029504.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug5029504.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JComboBox/bug5029504.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JComboBox/bug5029504.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,116 @@ +/* + * 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. + */ + +/* + @test + @bug 5029504 + @summary Empty JComboBox drop-down list is unexpectedly high + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.plaf.basic.BasicComboBoxUI; +import javax.swing.plaf.basic.BasicComboPopup; +import javax.swing.event.PopupMenuListener; +import javax.swing.event.PopupMenuEvent; + +public class bug5029504 { + + static volatile boolean passed = true; + static volatile JFrame mainFrame; + static volatile JComboBox comboBox; + static volatile BasicComboPopup ourPopup = null; + + public static void main(String[] args) throws Exception { + try { + SwingUtilities.invokeAndWait(bug5029504::createUI); + runTest(); + if (!passed) { + throw new RuntimeException( + "Popup of empty JComboBox is too high. Test failed."); + } + } finally { + if (mainFrame != null) { + SwingUtilities.invokeAndWait(mainFrame::dispose); + } + } + } + + static void createUI() { + mainFrame = new JFrame("Bug4924758"); + comboBox = new JComboBox(); + comboBox.setUI(new MyComboBoxUI()); + comboBox.addPopupMenuListener(new PopupMenuListener() { + public void popupMenuWillBecomeVisible(PopupMenuEvent e) {} + + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + if (ourPopup != null) { + int comboHeight = comboBox.getHeight(); + int popupHeight = ourPopup.getHeight(); + if (popupHeight > comboHeight*2) { + passed = false; + } + } + } + + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + mainFrame.setLayout(new BorderLayout()); + mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + mainFrame.add(comboBox, BorderLayout.CENTER); + mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); + mainFrame.validate(); + mainFrame.setVisible(true); + } + + static void runTest() throws Exception { + Robot robot = new Robot(); + robot.delay(2000); + Point p = comboBox.getLocationOnScreen(); + Dimension size = comboBox.getSize(); + p.x += size.width / 2; + p.y += size.height / 2; + robot.mouseMove(p.x, p.y); + robot.keyPress(KeyEvent.VK_ENTER); + robot.delay(50); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.delay(2000); + } + + static class MyComboBoxUI extends BasicComboBoxUI { + public void setPopupVisible(JComboBox c, boolean v) { + if (popup instanceof BasicComboPopup) { + ourPopup = (BasicComboPopup) popup; + } + super.setPopupVisible(c, v); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JRadioButton/bug4380543.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JRadioButton/bug4380543.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JRadioButton/bug4380543.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JRadioButton/bug4380543.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,135 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4380543 + * @key headful + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary setMargin() does not work for AbstractButton + * @run main/manual bug4380543 +*/ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.Insets; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +public class bug4380543 { + static TestFrame testObj; + static String instructions + = + "INSTRUCTIONS:\n" + + " 1. Check if the Left inset(margin) is set visually\n" + + " similar to other three sides around the Radio Button\n" + + " and CheckBox (insets set to 20 on all 4 sides).\n" + + " 2. Rendering depends on OS and supported Look and Feels.\n" + + " Verify only with those L&F where margins are visible.\n" + + " 3. If the Left inset(margin) appears too small, press Fail,\n" + + " else press Pass." + ; + static PassFailJFrame passFailJFrame; + + public static void main(String[] args) throws Exception { + + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + try { + passFailJFrame = new PassFailJFrame(instructions); + testObj = new TestFrame(); + //Adding the Test Frame to handle dispose + PassFailJFrame.addTestFrame(testObj); + PassFailJFrame.positionTestFrame(testObj, PassFailJFrame.Position.HORIZONTAL); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + passFailJFrame.awaitAndCheck(); + } +} + +class TestFrame extends JFrame implements ActionListener { + public TestFrame() { + initComponents(); + } + + public void initComponents() { + JPanel p = new JPanel(); + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS)); + + JRadioButton rb = new JRadioButton("JRadioButton"); + rb.setMargin(new Insets(20, 20, 20, 20)); + rb.setBackground(Color.GREEN); + rb.setAlignmentX(0.5f); + buttonsPanel.add(rb); + + JCheckBox cb = new JCheckBox("JCheckBox"); + cb.setMargin(new Insets(20, 20, 20, 20)); + cb.setBackground(Color.YELLOW); + cb.setAlignmentX(0.5f); + buttonsPanel.add(cb); + + getContentPane().add(buttonsPanel); + UIManager.LookAndFeelInfo[] lookAndFeel = UIManager.getInstalledLookAndFeels(); + for (UIManager.LookAndFeelInfo look : lookAndFeel) { + JButton btn = new JButton(look.getName()); + btn.setActionCommand(look.getClassName()); + btn.addActionListener(this); + p.add(btn); + } + + getContentPane().add(p,BorderLayout.SOUTH); + + setSize(500, 300); + setVisible(true); + } + + private static void setLookAndFeel(String laf) { + try { + UIManager.setLookAndFeel(laf); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Unsupported L&F: " + laf); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + //Changing the Look and Feel on user selection + public void actionPerformed(ActionEvent e) { + setLookAndFeel(e.getActionCommand()); + SwingUtilities.updateComponentTreeUI(this); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -89,6 +89,12 @@ buttonPressed = false; String lafName = laf.getClassName(); System.out.println("Testing L&F: " + lafName); + + // Ignore obsolete/deprecated Motif + if (lafName.contains("Motif")) { + System.out.println("Skipped Motif"); + continue; + } SwingUtilities.invokeAndWait(() -> { setLookAndFeel(lafName); createUI(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JSpinner/4788637/bug4788637.java 2023-10-06 05:33:33.000000000 +0000 @@ -21,11 +21,16 @@ * questions. */ +import java.io.File; + +import java.awt.image.BufferedImage; +import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.event.InputEvent; import javax.swing.JFrame; @@ -38,8 +43,10 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.imageio.ImageIO; import static javax.swing.UIManager.getInstalledLookAndFeels; + /** * @test * @bug 4788637 7124307 @@ -52,15 +59,15 @@ private static JFrame fr; private static Robot robot; - private int step; - private boolean spinnerValueChanged[] = {false, false, false}; + private int step = 0; + private volatile boolean spinnerValueChanged[] = {false, false, false}; - private static Point p; - private static Rectangle rect; + private static volatile Point p; + private static volatile Rectangle rect; public static void main(final String[] args) throws Exception { robot = new Robot(); - robot.setAutoDelay(50); + robot.setAutoDelay(100); robot.setAutoWaitForIdle(true); for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { SwingUtilities.invokeAndWait(() -> setLookAndFeel(laf)); @@ -68,6 +75,7 @@ try { SwingUtilities.invokeAndWait(app::createAndShowGUI); robot.waitForIdle(); + robot.delay(1000); SwingUtilities.invokeAndWait(()-> { spinner.requestFocus(); p = spinner.getLocationOnScreen(); @@ -106,9 +114,11 @@ public void start() { try { Thread.sleep(1000); + System.out.println("p " + p + " rect " + rect); // Move mouse to the up arrow button robot.mouseMove(p.x+rect.width-3, p.y+3); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + synchronized (bug4788637.this) { if (!spinnerValueChanged[step]) { bug4788637.this.wait(3000); @@ -123,6 +133,7 @@ bug4788637.this.wait(3000); } } + robot.waitForIdle(); // Move mouse to the up arrow button robot.mouseMove(p.x+rect.width-3, p.y+3); @@ -132,8 +143,10 @@ bug4788637.this.wait(3000); } } + robot.waitForIdle(); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); } catch(Throwable t) { throw new RuntimeException(t); } @@ -145,6 +158,15 @@ if (!spinnerValueChanged[0] || spinnerValueChanged[1] || !spinnerValueChanged[2]) { + System.out.println("!spinnerValueChanged[0] " + !spinnerValueChanged[0] + + " spinnerValueChanged[1] " + spinnerValueChanged[1] + + " !spinnerValueChanged[2] " + !spinnerValueChanged[2]); + try { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screen = new Rectangle(0, 0, (int) screenSize.getWidth(), (int) screenSize.getHeight()); + BufferedImage fullScreen = robot.createScreenCapture(screen); + ImageIO.write(fullScreen, "png", new File("fullScreen.png")); + } catch (Exception e) {} throw new Error("JSpinner buttons don't conform to most platform conventions"); } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JSpinner/JSpinnerFocusTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,121 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact 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 4516019 + * @summary Verify that clicking on the increment/decrement buttons + * of the spinner gives focus to the spinner. + * @run main JSpinnerFocusTest + */ + +import java.awt.BorderLayout; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.InputEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JSpinner; +import javax.swing.JSpinner.DefaultEditor; +import javax.swing.SwingUtilities; + +public class JSpinnerFocusTest { + + JFrame jFrame; + JButton jButton; + JSpinner jSpinner; + Robot robot; + + volatile Rectangle bounds; + volatile boolean jTextFieldFocusStatus = false; + + private void createGUI() { + jFrame = new JFrame(); + jButton = new JButton(); + jSpinner = new JSpinner(); + + jFrame.setLayout(new BorderLayout()); + jFrame.add(jButton, BorderLayout.NORTH); + jFrame.add(jSpinner, BorderLayout.CENTER); + jFrame.setLocationRelativeTo(null); + jFrame.setSize(300, 300); + jFrame.setVisible(true); + } + + public void doTest() throws Exception { + try { + robot = new Robot(); + robot.setAutoDelay(400); + + SwingUtilities.invokeAndWait(() -> createGUI()); + + robot.waitForIdle(); + runTest(); + + robot.waitForIdle(); + SwingUtilities.invokeAndWait(() -> { + jTextFieldFocusStatus = ((DefaultEditor) jSpinner.getEditor()) + .getTextField().isFocusOwner(); + }); + if (!jTextFieldFocusStatus) { + throw new RuntimeException( + "Clicking on JSpinner buttons did not" + + " shift focus to the JSpinner"); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (jFrame != null) { + jFrame.dispose(); + } + }); + } + } + + private void runTest() throws Exception { + SwingUtilities.invokeAndWait(() -> { + bounds = new Rectangle(jSpinner.getLocationOnScreen(), + jSpinner.getSize()); + }); + + // Move cursor to place it in the spinner editor + robot.mouseMove(bounds.x + bounds.width / 2, + bounds.y + bounds.height / 2); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + // Move cursor to click spinner up arrow button + robot.mouseMove(bounds.x + bounds.width - 2, + bounds.y + bounds.height / 4); + + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + public static void main(String[] args) throws Exception { + new JSpinnerFocusTest().doTest(); + System.out.println("Test Passed"); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/4170447/bug4170447.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/4170447/bug4170447.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/4170447/bug4170447.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/4170447/bug4170447.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * 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 4170447 + @summary JTable: non-Icon data in Icon column. + @key headful +*/ + +import java.io.File; +import java.awt.Component; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableModel; + +public class bug4170447 { + + static volatile boolean failed = false; + static volatile JFrame frame = null; + + public static void main(String args[]) throws Exception { + SwingUtilities.invokeAndWait(bug4170447::createUI); + Thread.sleep(5000); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + if (failed) { + throw new RuntimeException("Some exception occurred..."); + } + } + + static void createUI() { + String imgDir = System.getProperty("test.src", "."); + String imgPath = imgDir + File.separator + "swing.small.gif"; + ImageIcon icn = new ImageIcon(imgPath,"test"); + final Object data[][] = { + {"CELL 0 0", icn}, + {"CELL 1 0", "String"} + }; + String[] str = {"Column 0", "Column 1"}; + + TableModel dataModel = new AbstractTableModel() { + public int getColumnCount() { return 2; } + public int getRowCount() { return 2; } + public Object getValueAt(int row, int col) {return data[row][col];} + public Class getColumnClass(int c) {return getValueAt(0, c).getClass();} + public boolean isCellEditable(int row, int col) {return getColumnClass(col) == String.class;} + public void setValueAt(Object aValue, int row, int column) {data[row][column] = aValue;} + }; + + MyTable tbl = new MyTable(dataModel); + JScrollPane sp = new JScrollPane(tbl); + frame = new JFrame("bug4170447"); + frame.getContentPane().add(sp); + frame.pack(); + frame.setVisible(true); + } + + static class MyTable extends JTable { + public MyTable(TableModel tm) { + super(tm); + } + + public Component prepareRenderer(TableCellRenderer rend, int row, int col) { + try { + return super.prepareRenderer(rend, row, col); + } catch (Exception e) { + e.printStackTrace(); + failed = true; + return null; + } + } + } +} Binary files /tmp/tmpqf9nh9_e/WmtU8sFA5F/openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/4170447/swing.small.gif and /tmp/tmpqf9nh9_e/hxiu8P4Qky/openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/4170447/swing.small.gif differ diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4098201.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4098201.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4098201.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4098201.java 2023-10-06 05:33:33.000000000 +0000 @@ -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. + */ + +/* + @test + @bug 4098201 + @summary Tests setRowHeight(int row, int height). +*/ + +import javax.swing.JTable; + +public class bug4098201 { + + public static void main(String args[]) { + JTable table = new JTable(4,3); + table.setRowHeight(1, table.getRowHeight()*2); + if (table.getRowHeight(0) * 2 != table.getRowHeight(1)) { + throw new Error("Can't set height for specified row..."); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4130356.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4130356.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4130356.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4130356.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,43 @@ +/* + * 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 4130356 + @summary JTable.setRowSelectionInterval(int, int) shouldn't accept invalid range +*/ + +import javax.swing.JTable; +import javax.swing.ListSelectionModel; + +public class bug4130356 { + + public static void main(String[] argv) { + JTable table = new JTable(4,3); + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + try { + table.setRowSelectionInterval(10,13); + throw new Error("Invalid arguments supported!!!"); + } catch (IllegalArgumentException iae) {} + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4159300.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4159300.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4159300.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4159300.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * 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 4159300 + @summary Tests that JTable processes tableChanged events quickly + @key headful +*/ + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Rectangle; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.DefaultTableModel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class bug4159300 { + + static volatile JFrame frame = null; + public static void main(String[] args) throws Exception { + SwingUtilities.invokeAndWait(bug4159300::createUI); + Thread.sleep(3000); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + + static void createUI() { + frame = new JFrame("bug4159300"); + Container c = frame.getContentPane(); + c.setLayout(new BorderLayout()); + // create table + Object[] columnNames = {"only column"}; + DefaultTableModel model = new DefaultTableModel(columnNames, 0); + Object[] row = makeRow(model.getRowCount()); + model.addRow(row); + + JTable table = new JTable(model); + c.add(new JScrollPane(table), BorderLayout.CENTER); + + // create button + JButton immediateButton = new JButton("Add row"); + immediateButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int rowCount = model.getRowCount(); + Object[] row = makeRow(rowCount); + model.addRow(row); + int rows = model.getRowCount(); + int lastRow = rows - 1; + table.setRowSelectionInterval(lastRow, lastRow); + Rectangle r = table.getCellRect(lastRow, 0, false); + table.scrollRectToVisible(r); + } + }); + c.add(immediateButton, BorderLayout.SOUTH); + frame.pack(); + frame.setVisible(true); + } + + static Object[] makeRow(int rowNumber) { + Object[] row = { ""+rowNumber }; + return row; + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4243159.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4243159.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4243159.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4243159.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * 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 4243159 + @summary Tests that JTable() do not throw ArrayIndexOutOfBoundsException +*/ + +import javax.swing.JTable; + +public class bug4243159 { + + /* Looks boring, but tests the no-args constructor works */ + public static void main(String[] argv) { + JTable table = new JTable(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4243313.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4243313.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4243313.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4243313.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * 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 4243313 + @summary Tests that instantiating JTable through reflection + does not throw ClassNotFoundException +*/ + +import java.beans.Beans; + +public class bug4243313 { + + public static void main(String[] argv) throws Exception { + Object table = Beans.instantiate(null, "javax.swing.JTable"); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4247487.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4247487.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4247487.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4247487.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * 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 4247487 + @summary Tests that the following methods of JTable are public: + int getAccessibleColumnAtIndex(int) + int getAccessibleRowAtIndex(int) + int getAccessibleIndexAt(int, int) +*/ + +import javax.swing.JTable; + +public class bug4247487 { + + static class TestTable extends JTable { + + public TestTable() { + super(new Object[][]{{"one", "two"}}, + new Object[]{"A", "B"}); + } + + public void test() { + int[] rowIndices = {0, 0, 1, 1}; + int[] colIndices = {0, 1, 0, 1}; + JTable.AccessibleJTable at = + (JTable.AccessibleJTable)getAccessibleContext(); + + for (int i=0; i<4; i++) { + if (at.getAccessibleRowAtIndex(i) != rowIndices[i]) { + throw new Error("Failed: wrong row index"); + } + if (at.getAccessibleColumnAtIndex(i) != colIndices[i]) { + throw new Error("Failed: wrong column index"); + } + } + if (at.getAccessibleIndexAt(0,0) != 0 || + at.getAccessibleIndexAt(0,1) != 1 || + at.getAccessibleIndexAt(1,0) != 2 || + at.getAccessibleIndexAt(1,1) != 3) { + + throw new Error("Failed: wrong index"); + } + } + } + + public static void main(String[] argv) { + TestTable test = new TestTable(); + test.test(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4248070.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4248070.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTable/bug4248070.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTable/bug4248070.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * 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 4248070 + @summary cellEditor bound in JTable. +*/ + +import javax.swing.JTable; +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; + +public class bug4248070 { + + public static void main(String[] argv) { + + BeanInfo bi = null; + + try { + bi = Introspector.getBeanInfo(JTable.class); + } catch (IntrospectionException e) { + } + + PropertyDescriptor[] pd = bi.getPropertyDescriptors(); + int i; + for (i=0; i { + frame = new JFrame(); + frame.setUndecorated(true); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JTableHeader th = new JTableHeader(); @@ -56,21 +70,33 @@ frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + point = frame.getLocationOnScreen(); + width = frame.getWidth(); + height = frame.getHeight(); + }); + int shift = 10; + int x = point.x; + int y = point.y + height/2; + for(int i = -shift; i < width + 2*shift; i++) { + robot.mouseMove(x++, y); + robot.waitForIdle(); } - }); - robot.waitForIdle(); - Point point = frame.getLocationOnScreen(); - int shift = 10; - int x = point.x; - int y = point.y + frame.getHeight()/2; - for(int i = -shift; i < frame.getWidth() + 2*shift; i++) { - robot.mouseMove(x++, y); - } - robot.waitForIdle(); - // 9 is a magic test number - if (MyTableHeaderUI.getTestValue() != 9) { - throw new RuntimeException("Unexpected test number " - + MyTableHeaderUI.getTestValue()); + robot.waitForIdle(); + // 9 is a magic test number + if (MyTableHeaderUI.getTestValue() != 9) { + throw new RuntimeException("Unexpected test number " + + MyTableHeaderUI.getTestValue()); + } + } finally { + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); } System.out.println("ok"); } @@ -83,6 +109,15 @@ Cursor cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); if (oldColumn != -1 && newColumn != -1 && header.getCursor() != cursor) { + try { + Dimension screenSize = + Toolkit.getDefaultToolkit().getScreenSize(); + Rectangle screen = new Rectangle(0, 0, + (int) screenSize.getWidth(), + (int) screenSize.getHeight()); + BufferedImage img = robot.createScreenCapture(screen); + ImageIO.write(img, "png", new java.io.File("image.png")); + } catch (Exception e) {} throw new RuntimeException("Wrong type of cursor!"); } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTextField/JapaneseReadingAttributes/JapaneseReadingAttributes.java openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTextField/JapaneseReadingAttributes/JapaneseReadingAttributes.java --- openjdk-lts-11.0.20.1+1/test/jdk/javax/swing/JTextField/JapaneseReadingAttributes/JapaneseReadingAttributes.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/javax/swing/JTextField/JapaneseReadingAttributes/JapaneseReadingAttributes.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 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 @@ -98,7 +98,7 @@ private static void setupUI() { String description = " 1. Go to \"Language Preferences -> Add a Language" + "\" and add \"Japanese\"\n" - + " 2. Set current IM to \"Japanese\" \n" + + " 2. Set current IM to \"Japanese\" and IME option to \"Full width Katakana\" \n" + " 3. Try typing in the text field to ensure" + " that Japanese IME has been successfully" + " selected \n" diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java openjdk-lts-11.0.21+9/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/internal/jline/AbstractWindowsTerminalTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -56,7 +56,7 @@ return is.read(); } }; - var t = new AbstractWindowsTerminal(out, "test", "vt100", null, -1, false, SignalHandler.SIG_DFL, isWrapper) { + var t = new AbstractWindowsTerminal(out, "test", "vt100", null, false, SignalHandler.SIG_DFL, isWrapper) { @Override protected int getConsoleMode() { return -1; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/internal/jline/KeyConversionTest.java openjdk-lts-11.0.21+9/test/jdk/jdk/internal/jline/KeyConversionTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/internal/jline/KeyConversionTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/internal/jline/KeyConversionTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -59,7 +59,7 @@ void checkKeyConversion(KeyEvent event, String expected) throws IOException { StringBuilder result = new StringBuilder(); new AbstractWindowsTerminal(new StringWriter(), "", "windows", Charset.forName("UTF-8"), - 0, true, SignalHandler.SIG_DFL, in -> in) { + true, SignalHandler.SIG_DFL, in -> in) { @Override protected int getConsoleMode() { return 0; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/internal/jline/OSUtilsTest.java openjdk-lts-11.0.21+9/test/jdk/jdk/internal/jline/OSUtilsTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/internal/jline/OSUtilsTest.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/internal/jline/OSUtilsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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 8304498 + * @summary Verify the OSUtils class is initialized properly + * @modules jdk.internal.le/jdk.internal.org.jline.utils + */ + +import jdk.internal.org.jline.utils.OSUtils; + +public class OSUtilsTest { + public static void main(String... args) throws Exception { + new OSUtilsTest().run(); + } + + void run() throws Exception { + runTestTest(); + } + + void runTestTest() throws Exception { + if (OSUtils.IS_WINDOWS) { + return ; //skip on Windows + } + + Process p = new ProcessBuilder(OSUtils.TEST_COMMAND, "-z", "").inheritIO().start(); + if (p.waitFor() != 0) { + throw new AssertionError("Unexpected result!"); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/event/sampling/TestNative.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/event/sampling/TestNative.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/event/sampling/TestNative.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/event/sampling/TestNative.java 2023-10-06 05:33:33.000000000 +0000 @@ -57,7 +57,7 @@ public static void main(String[] args) throws Exception { String lib = System.getProperty("test.nativepath"); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, "-Djava.library.path=" + lib, "jdk.jfr.event.sampling.TestNative$Test"); + ProcessBuilder pb = ProcessTools.createTestJvm("-Djava.library.path=" + lib, "jdk.jfr.event.sampling.TestNative$Test"); OutputAnalyzer output = ProcessTools.executeProcess(pb); output.shouldHaveExitValue(0); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/event/security/TestX509CertificateEvent.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -23,7 +23,6 @@ package jdk.jfr.event.security; -import java.security.cert.CertificateFactory; import java.util.List; import jdk.jfr.Recording; @@ -31,36 +30,63 @@ import jdk.test.lib.Asserts; import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.Events; +import jdk.test.lib.jfr.VoidFunction; import jdk.test.lib.security.TestCertificate; /* * @test - * @bug 8148188 + * @bug 8148188 8292033 * @summary Enhance the security libraries to record events of interest * @key jfr * @requires vm.hasJFR + * @modules java.base/sun.security.x509 java.base/sun.security.tools.keytool * @library /test/lib * @run main/othervm jdk.jfr.event.security.TestX509CertificateEvent */ public class TestX509CertificateEvent { - public static void main(String[] args) throws Exception { + public static void main(String[] args) throws Throwable { + testCall(() -> { + // test regular cert construction + TestCertificate.ONE.certificate(); + TestCertificate.TWO.certificate(); + // Generate twice to make sure we (now) capture all generate cert events + TestCertificate.ONE.certificate(); + TestCertificate.TWO.certificate(); + }, 4, true); + + testCall(() -> { + // test generateCertificates method + TestCertificate.certificates(); + }, 2, true); + + testCall(() -> { + // test generateCertPath method + TestCertificate.certPath(); + }, 4, true); + + testCall(() -> { + // test keytool cert generation with JFR enabled + // The keytool test will load the dedicated keystore + // and call CertificateFactory.generateCertificate + // cacerts + TestCertificate.keyToolTest(); + }, -1, false); + } + + private static void testCall(VoidFunction f, int expected, boolean runAsserts) throws Throwable { try (Recording recording = new Recording()) { recording.enable(EventNames.X509Certificate); recording.start(); - - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - TestCertificate.ONE.generate(cf); - TestCertificate.TWO.generate(cf); - // Generate twice to make sure only one event per certificate is generated - TestCertificate.ONE.generate(cf); - TestCertificate.TWO.generate(cf); - + f.run(); recording.stop(); - List events = Events.fromRecording(recording); - Asserts.assertEquals(events.size(), 2, "Incorrect number of X509Certificate events"); - assertEvent(events, TestCertificate.ONE); - assertEvent(events, TestCertificate.TWO); + if (expected >= 0) { + Asserts.assertEquals(events.size(), expected, "Incorrect number of events"); + } + if (runAsserts) { + assertEvent(events, TestCertificate.ONE); + assertEvent(events, TestCertificate.TWO); + } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/event/security/TestX509ValidationEvent.java 2023-10-06 05:33:33.000000000 +0000 @@ -42,7 +42,7 @@ * @key jfr * @requires vm.hasJFR * @library /test/lib - * @modules jdk.jfr/jdk.jfr.events + * @modules jdk.jfr/jdk.jfr.events java.base/sun.security.x509 java.base/sun.security.tools.keytool * @run main/othervm jdk.jfr.event.security.TestX509ValidationEvent */ public class TestX509ValidationEvent { @@ -50,8 +50,8 @@ try (Recording recording = new Recording()) { recording.enable(EventNames.X509Validation); recording.start(); - // intermeditate certificate test - TestCertificate.generateChain(false); + // intermediate certificate test + TestCertificate.generateChain(false, true); recording.stop(); List events = Events.fromRecording(recording); Asserts.assertEquals(events.size(), 3, "Incorrect number of events"); @@ -62,12 +62,23 @@ recording.enable(EventNames.X509Validation); recording.start(); // self signed certificate test - TestCertificate.generateChain(true); + TestCertificate.generateChain(true, true); recording.stop(); List events = Events.fromRecording(recording); Asserts.assertEquals(events.size(), 2, "Incorrect number of events"); assertEvent2(events); } + + try (Recording recording = new Recording()) { + recording.enable(EventNames.X509Validation); + recording.start(); + // intermediate certificate test, with no Cert for trust anchor + TestCertificate.generateChain(true, false); + recording.stop(); + List events = Events.fromRecording(recording); + Asserts.assertEquals(events.size(), 2, "Incorrect number of events"); + assertEvent3(events); + } } private static void assertEvent1(List events) throws Exception { @@ -104,6 +115,28 @@ case 2: Events.assertField(e, "certificateId") .equal(TestCertificate.ROOT_CA.certId); + break; + default: + System.out.println(events); + throw new Exception("Unexpected position:" + pos); + } + } + } + /* + * Self signed certificate test + */ + private static void assertEvent3(List events) throws Exception { + for (RecordedEvent e : events) { + int pos = e.getInt("certificatePosition"); + switch (pos) { + // use public key of cert provided in TrustAnchor + case 1: + Asserts.assertEquals(e.getLong("certificateId"), + Long.valueOf(TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode())); + break; + case 2: + Events.assertField(e, "certificateId") + .equal(TestCertificate.ROOT_CA.certId); break; default: System.out.println(events); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/jvm/TestDumpOnCrash.java 2023-10-06 05:33:33.000000000 +0000 @@ -91,7 +91,7 @@ private static long runProcess(String crasher, String signal, boolean disk) throws Exception { System.out.println("Test case for crasher " + crasher); final String flightRecordingOptions = "dumponexit=true,disk=" + Boolean.toString(disk); - Process p = ProcessTools.createJavaProcessBuilder(true, + Process p = ProcessTools.createTestJvm( "-Xmx64m", "-XX:-TransmitErrorReport", "-XX:-CreateCoredumpOnCrash", diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/jvm/TestJfrJavaBase.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/jvm/TestJfrJavaBase.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/jvm/TestJfrJavaBase.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/jvm/TestJfrJavaBase.java 2023-10-06 05:33:33.000000000 +0000 @@ -51,7 +51,7 @@ public static void main(String[] args) throws Exception { OutputAnalyzer output; if (args.length == 0) { - output = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder(false, + output = ProcessTools.executeProcess(ProcessTools.createJavaProcessBuilder( "-Dtest.jdk=" + System.getProperty("test.jdk"), "--limit-modules", "java.base", "-cp", System.getProperty("java.class.path"), TestJfrJavaBase.class.getName(), "runtest")); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestDumpOnExit.java 2023-10-06 05:33:33.000000000 +0000 @@ -94,7 +94,7 @@ } private static void testDumponExit(Supplier p,String... args) throws Exception, IOException { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args); + ProcessBuilder pb = ProcessTools.createTestJvm(args); OutputAnalyzer output = ProcessTools.executeProcess(pb); System.out.println(output.getOutput()); output.shouldHaveExitValue(0); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestMemoryOptions.java 2023-10-06 05:33:33.000000000 +0000 @@ -485,21 +485,19 @@ final String flightRecorderOptions = tc.getTestString(); ProcessBuilder pb; if (flightRecorderOptions != null) { - pb = ProcessTools.createJavaProcessBuilder(true, - "--add-exports=jdk.jfr/jdk.jfr.internal=ALL-UNNAMED", - "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", - flightRecorderOptions, - "-XX:StartFlightRecording", - SUT.class.getName(), - tc.getTestName()); + pb = ProcessTools.createTestJvm("--add-exports=jdk.jfr/jdk.jfr.internal=ALL-UNNAMED", + "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", + flightRecorderOptions, + "-XX:StartFlightRecording", + SUT.class.getName(), + tc.getTestName()); } else { // default, no FlightRecorderOptions passed - pb = ProcessTools.createJavaProcessBuilder(true, - "--add-exports=jdk.jfr/jdk.jfr.internal=ALL-UNNAMED", - "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", - "-XX:StartFlightRecording", - SUT.class.getName(), - tc.getTestName()); + pb = ProcessTools.createTestJvm("--add-exports=jdk.jfr/jdk.jfr.internal=ALL-UNNAMED", + "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:StartFlightRecording", + SUT.class.getName(), + tc.getTestName()); } System.out.println("Driver launching SUT with string: " + flightRecorderOptions != null ? flightRecorderOptions : "default"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestMultipleStartupRecordings.java 2023-10-06 05:33:33.000000000 +0000 @@ -57,14 +57,14 @@ private static void launchUnary(String options) throws Exception { String recording1 = START_FLIGHT_RECORDING + (options != null ? options : ""); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, recording1, MainClass.class.getName()); + ProcessBuilder pb = ProcessTools.createTestJvm(recording1, MainClass.class.getName()); test(pb, "Started recording 1"); } private static void launchBinary(String options1, String options2) throws Exception { String recording1 = START_FLIGHT_RECORDING + (options1 != null ? options1 : ""); String recording2 = START_FLIGHT_RECORDING + (options2 != null ? options2 : ""); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, recording1, recording2, MainClass.class.getName()); + ProcessBuilder pb = ProcessTools.createTestJvm(recording1, recording2, MainClass.class.getName()); test(pb, "Started recording 1", "Started recording 2"); } @@ -72,7 +72,7 @@ String recording1 = START_FLIGHT_RECORDING + (options1 != null ? options1 : ""); String recording2 = START_FLIGHT_RECORDING + (options2 != null ? options2 : ""); String recording3 = START_FLIGHT_RECORDING + (options3 != null ? options3 : ""); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, recording1, recording2, recording3, MainClass.class.getName()); + ProcessBuilder pb = ProcessTools.createTestJvm(recording1, recording2, recording3, MainClass.class.getName()); test(pb, "Started recording 1", "Started recording 2", "Started recording 3"); } @@ -96,7 +96,7 @@ String flightRecorderOptions = FLIGHT_RECORDER_OPTIONS + "=maxchunksize=8m"; String recording1 = START_FLIGHT_RECORDING + "=filename=recording1.jfr"; String recording2 = START_FLIGHT_RECORDING + "=name=myrecording,filename=recording2.jfr"; - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, flightRecorderOptions, recording1, recording2, MainClass.class.getName()); + ProcessBuilder pb = ProcessTools.createTestJvm(flightRecorderOptions, recording1, recording2, MainClass.class.getName()); test(pb, "Started recording 1", "Started recording 2"); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestRetransformUsingLog.java 2023-10-06 05:33:33.000000000 +0000 @@ -106,7 +106,7 @@ } System.out.println(); System.out.println(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args.toArray(new String[0])); + ProcessBuilder pb = ProcessTools.createTestJvm(args); OutputAnalyzer out = ProcessTools.executeProcess(pb); System.out.println(out.getOutput()); verifier.accept(out); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestStartDuration.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestStartDuration.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestStartDuration.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestStartDuration.java 2023-10-06 05:33:33.000000000 +0000 @@ -55,7 +55,7 @@ } private static void testDurationInRange(String duration, Duration durationString, boolean wait) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:StartFlightRecording=name=TestStartDuration,duration=" + duration, TestValues.class.getName(), durationString.toString(), wait ? "wait" : ""); OutputAnalyzer out = ProcessTools.executeProcess(pb); @@ -65,7 +65,7 @@ private static void testDurationJavaVersion(String duration, boolean inRange) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:StartFlightRecording=name=TestStartDuration,duration=" + duration, "-version"); OutputAnalyzer out = ProcessTools.executeProcess(pb); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestStartName.java openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestStartName.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/jfr/startupargs/TestStartName.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/jfr/startupargs/TestStartName.java 2023-10-06 05:33:33.000000000 +0000 @@ -47,7 +47,7 @@ } private static void testName(String recordingName, boolean validName) throws Exception { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( "-XX:StartFlightRecording=name=" + recordingName, TestName.class.getName(), recordingName); OutputAnalyzer out = ProcessTools.executeProcess(pb); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/net/Sockets/QuickAckTest.java openjdk-lts-11.0.21+9/test/jdk/jdk/net/Sockets/QuickAckTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/net/Sockets/QuickAckTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/net/Sockets/QuickAckTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -26,7 +26,7 @@ * @bug 8145635 * @summary Add TCP_QUICKACK socket option * @modules jdk.net - * @run main QuickAckTest + * @run main/othervm QuickAckTest */ import java.io.IOException; import java.net.DatagramSocket; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java openjdk-lts-11.0.21+9/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/nio/zipfs/ZipFSOutputStreamTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -37,15 +37,15 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; import java.util.Map; -import java.util.Random; /** * @test * @summary Verify that the outputstream created for zip file entries, through the ZipFileSystem * works fine for varying sizes of the zip file entries - * @bug 8190753 8011146 + * @bug 8190753 8011146 8279536 * @run testng/timeout=300 ZipFSOutputStreamTest */ public class ZipFSOutputStreamTest { @@ -90,7 +90,9 @@ public void testOutputStream(final Map env) throws Exception { final URI uri = URI.create("jar:" + ZIP_FILE.toUri() ); final byte[] chunk = new byte[1024]; - new Random().nextBytes(chunk); + // fill it with some fixed content (the fixed content will later on help ease + // the verification of the content written out) + Arrays.fill(chunk, (byte) 42); try (final FileSystem zipfs = FileSystems.newFileSystem(uri, env)) { // create the zip with varying sized entries for (final Map.Entry entry : ZIP_ENTRIES.entrySet()) { @@ -98,9 +100,12 @@ if (entryPath.getParent() != null) { Files.createDirectories(entryPath.getParent()); } + long start = System.currentTimeMillis(); try (final OutputStream os = Files.newOutputStream(entryPath)) { writeAsChunks(os, chunk, entry.getValue()); } + System.out.println("Wrote entry " + entryPath + " of bytes " + entry.getValue() + + " in " + (System.currentTimeMillis() - start) + " milli seconds"); } } // now verify the written content @@ -111,15 +116,15 @@ final byte[] buf = new byte[chunk.length]; int numRead; long totalRead = 0; + long start = System.currentTimeMillis(); while ((numRead = is.read(buf)) != -1) { totalRead += numRead; // verify the content - for (int i = 0, chunkoffset = (int) ((totalRead - numRead) % chunk.length); - i < numRead; i++, chunkoffset++) { - Assert.assertEquals(buf[i], chunk[chunkoffset % chunk.length], - "Unexpected content in " + entryPath); - } + Assert.assertEquals(Arrays.mismatch(buf, 0, numRead, chunk, 0, numRead), -1, + "Unexpected content in " + entryPath); } + System.out.println("Read entry " + entryPath + " of bytes " + totalRead + + " in " + (System.currentTimeMillis() - start) + " milli seconds"); Assert.assertEquals(totalRead, (long) entry.getValue(), "Unexpected number of bytes read from zip entry " + entryPath); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/security/logging/TestX509CertificateLog.java openjdk-lts-11.0.21+9/test/jdk/jdk/security/logging/TestX509CertificateLog.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/security/logging/TestX509CertificateLog.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/security/logging/TestX509CertificateLog.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -23,7 +23,6 @@ package jdk.security.logging; -import java.security.cert.CertificateFactory; import jdk.test.lib.security.TestCertificate; /* @@ -31,6 +30,7 @@ * @bug 8148188 * @summary Enhance the security libraries to record events of interest * @library /test/lib /test/jdk + * @modules java.base/sun.security.x509 java.base/sun.security.tools.keytool * @run main/othervm jdk.security.logging.TestX509CertificateLog LOGGING_ENABLED * @run main/othervm jdk.security.logging.TestX509CertificateLog LOGGING_DISABLED */ @@ -58,9 +58,8 @@ public static class GenerateX509Certicate { public static void main(String[] args) throws Exception { - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - TestCertificate.ONE.generate(cf); - TestCertificate.TWO.generate(cf); + TestCertificate.ONE.certificate(); + TestCertificate.TWO.certificate(); } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/jdk/security/logging/TestX509ValidationLog.java openjdk-lts-11.0.21+9/test/jdk/jdk/security/logging/TestX509ValidationLog.java --- openjdk-lts-11.0.20.1+1/test/jdk/jdk/security/logging/TestX509ValidationLog.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/jdk/security/logging/TestX509ValidationLog.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -30,6 +30,7 @@ * @bug 8148188 * @summary Enhance the security libraries to record events of interest * @library /test/lib /test/jdk + * @modules java.base/sun.security.x509 java.base/sun.security.tools.keytool * @run main/othervm jdk.security.logging.TestX509ValidationLog LOGGING_ENABLED * @run main/othervm jdk.security.logging.TestX509ValidationLog LOGGING_DISABLED */ @@ -43,14 +44,19 @@ l.addExpected("FINE: ValidationChain: " + TestCertificate.ROOT_CA.certId + ", " + TestCertificate.ROOT_CA.certId); + l.addExpected("FINE: ValidationChain: " + + TestCertificate.ROOT_CA.certificate().getPublicKey().hashCode() + + ", " + TestCertificate.ROOT_CA.certId); l.testExpected(); } public static class GenerateCertificateChain { public static void main(String[] args) throws Exception { - TestCertificate.generateChain(false); + TestCertificate.generateChain(false, true); // self signed test - TestCertificate.generateChain(true); + TestCertificate.generateChain(true, true); + // no cert for trust anchor + TestCertificate.generateChain(true, false); } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/ProblemList.txt openjdk-lts-11.0.21+9/test/jdk/ProblemList.txt --- openjdk-lts-11.0.20.1+1/test/jdk/ProblemList.txt 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/ProblemList.txt 2023-10-06 05:33:33.000000000 +0000 @@ -472,7 +472,7 @@ # below test fails only on Win 7 java/awt/font/FontNames/LocaleFamilyNames.java 8213129 windows-all -java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223 linux-all,solaris-all,windows-all +java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 7099223,8274106 macosx-aarch64,linux-all,solaris-all,windows-all java/awt/keyboard/AllKeyCode/AllKeyCode.java 8242930 macosx-all java/awt/FullScreen/8013581/bug8013581.java 8169471 macosx-all java/awt/event/MouseEvent/RobotLWTest/RobotLWTest.java 8233568 macosx-all @@ -613,19 +613,14 @@ sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-all -sun/security/tools/jarsigner/compatibility/SignTwice.java 8217375 windows-all sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 8026393 generic-all javax/net/ssl/DTLS/PacketLossRetransmission.java 8169086 macosx-x64 -javax/net/ssl/DTLS/RespondToRetransmit.java 8169086 macosx-x64 +javax/net/ssl/DTLS/RespondToRetransmit.java 8169086 macosx-all javax/net/ssl/DTLS/CipherSuite.java 8202059 macosx-x64 sun/security/provider/KeyStore/DKSTest.sh 8180266 windows-all -sun/security/pkcs11/KeyStore/SecretKeysBasic.java 8209398 generic-all - -security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 8224768 generic-all - sun/security/smartcardio/TestChannel.java 8039280 generic-all sun/security/smartcardio/TestConnect.java 8039280 generic-all sun/security/smartcardio/TestConnectAgain.java 8039280 generic-all @@ -644,6 +639,7 @@ com/sun/security/sasl/gsskerb/NoSecurityLayer.java 8039280 generic-all javax/security/auth/kerberos/KerberosHashEqualsTest.java 8039280 generic-all javax/security/auth/kerberos/KerberosTixDateTest.java 8039280 generic-all +javax/security/auth/callback/PasswordCallback/CheckCleanerBound.java 8285785,8286045,8287596 generic-all sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.java 8039280 generic-all sun/security/provider/PolicyParser/ExtDirsChange.java 8039280 generic-all sun/security/provider/PolicyParser/PrincipalExpansionError.java 8039280 generic-all @@ -741,12 +737,11 @@ java/awt/Robot/HiDPIScreenCapture/HiDPIRobotScreenCaptureTest.java 8282270 windows-all # Several tests which fail on some hidpi systems -java/awt/GraphicsDevice/DisplayModes/CycleDMImage.java 8274106 macosx-aarch64 java/awt/Window/8159168/SetShapeTest.java 8274106 macosx-aarch64 java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java 8274106 macosx-aarch64 javax/swing/JFrame/8175301/ScaledFrameBackgroundTest.java 8274106 macosx-aarch64 -sanity/client/SwingSet/src/ToolTipDemoTest.java 8225012 windows-all,macosx-all +sanity/client/SwingSet/src/ToolTipDemoTest.java 8293001 linux-all javax/swing/SwingWorker/6432565/bug6432565.java 8199077 generic-all javax/swing/SwingWorker/6880336/NestedWorkers.java 8199049 windows-all @@ -865,9 +860,10 @@ # jdk_jfr jdk/jfr/event/sampling/TestNative.java 8202142 generic-all +jdk/jfr/event/sampling/TestStackFrameLineNumbers.java 8313802 linux-all,windows-all jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java 8228990,8229370 generic-all jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic-all jdk/jfr/event/oldobject/TestLargeRootSet.java 8205651 generic-all - + ############################################################################ diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sanity/client/SwingSet/src/ToolTipDemoTest.java openjdk-lts-11.0.21+9/test/jdk/sanity/client/SwingSet/src/ToolTipDemoTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sanity/client/SwingSet/src/ToolTipDemoTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sanity/client/SwingSet/src/ToolTipDemoTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -38,6 +38,7 @@ import org.jtregext.GuiTestListener; import org.netbeans.jemmy.ClassReference; +import org.netbeans.jemmy.JemmyProperties; import org.netbeans.jemmy.operators.JComponentOperator; import org.netbeans.jemmy.operators.JFrameOperator; import org.netbeans.jemmy.operators.JLabelOperator; @@ -79,12 +80,20 @@ @Test(dataProvider = "availableLookAndFeels", dataProviderClass = TestHelpers.class) public void test(String lookAndFeel) throws Exception { UIManager.setLookAndFeel(lookAndFeel); + + JemmyProperties.setCurrentDispatchingModel(JemmyProperties.ROBOT_MODEL_MASK | + JemmyProperties.SMOOTH_ROBOT_MODEL_MASK); + new ClassReference(ToolTipDemo.class.getCanonicalName()).startApplication(); JFrameOperator frameOperator = new JFrameOperator(DEMO_TITLE); frameOperator.setComparator(EXACT_STRING_COMPARATOR); // Setting the tooltip dismiss delay ToolTipManager.sharedInstance().setDismissDelay(TOOLTIP_DISMISS_DELAY); + //activate window + frameOperator.clickMouse(); + frameOperator.moveMouse(-1, -1); + // Verifying the plain tooltip properties checkToolTip(frameOperator, PLAIN_TOOLTIP_COMP_TITLE, PLAIN_TOOLTIP_TEXT); @@ -116,18 +125,15 @@ */ private void checkToolTip(JFrameOperator frameOperator, String compTitle, String toolTipText) { - JLabelOperator toolTipHostComp = new JLabelOperator(frameOperator, compTitle); JToolTipOperator toolTipOperator = new JToolTipOperator(toolTipHostComp.showToolTip()); toolTipOperator.waitTipText(toolTipText); checkToolTipLocation(toolTipHostComp, toolTipOperator); - - // Dismissing the tooltip by mouse click - toolTipHostComp.clickMouse(); + // Dismissing the tooltip by moving the mouse out + toolTipHostComp.moveMouse(-1, -1); toolTipOperator.waitComponentShowing(false); - } private void checkToolTipLocation(JComponentOperator componentOpertor, diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java --- openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 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 @@ -33,221 +33,185 @@ /* * Obtain test artifacts for Actalis CA from: * - * Test web site with *active *TLS Server certificate: - * https://ssltest-a.actalis.it:8443 - * If doesn't work then use certificate of https://www.actalis.it + * Test website with *active* TLS Server certificate: + * https://ssltest-active.actalis.it/ * - * Test web site with *revoked *TLS Server certificate: - * https://ssltest-r.actalis.it:8444 + * Test website with *revoked* TLS Server certificate: + * https://ssltest-revoked.actalis.it/ * - * Test web site with *expired *TLS Server certificate: - * https://ssltest-e.actalis.it:8445 + * Test website with *expired* TLS Server certificate: + * https://ssltest-expired.actalis.it/ */ public class ActalisCA { - // Owner: CN=Actalis Extended Validation Server CA G1, - // O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // Issuer: CN=Actalis Authentication Root CA, O=Actalis S.p.A./03358520967, - // L=Milan, C=IT - private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" - + "MIIGTDCCBDSgAwIBAgIIMtYr/GdQGsswDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\n" - + "BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w\n" - + "MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\n" - + "IENBMB4XDTE1MDUxNDA3MDAzOFoXDTMwMDUxNDA3MDAzOFowgYcxCzAJBgNVBAYT\n" - + "AklUMQ8wDQYDVQQIDAZNaWxhbm8xDzANBgNVBAcMBk1pbGFubzEjMCEGA1UECgwa\n" - + "QWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxMTAvBgNVBAMMKEFjdGFsaXMgRXh0\n" - + "ZW5kZWQgVmFsaWRhdGlvbiBTZXJ2ZXIgQ0EgRzEwggEiMA0GCSqGSIb3DQEBAQUA\n" - + "A4IBDwAwggEKAoIBAQD1Ygc1CwmqXqjd3dTEKMLUwGdb/3+00ytg0uBb4RB+89/O\n" - + "4K/STFZcGUjcCq6Job5cmxZBGyRRBYfCEn4vg8onedFztkO0NvD04z4wLFyxjSRT\n" - + "bcMm2d+/Xci5XLA3Q9wG8TGzHTVQKmdvFpQ7b7EsmOc0uXA7w3UGhLjb2EYpu/Id\n" - + "uZ1LUTyEOHc3XHXI3a3udkRBDs/bObTcbte80DPbNetRFB+jHbIw5sH171IeBFGN\n" - + "PB92Iebp01yE8g3X9RqPXrrV7ririEtwFMYp+KgA8BRHxsoNV3xZmhdzJm0AMzC2\n" - + "waLM3H562xPM0UntAYh2pRrAUUtgURRizCT1kr6tAgMBAAGjggHVMIIB0TBBBggr\n" - + "BgEFBQcBAQQ1MDMwMQYIKwYBBQUHMAGGJWh0dHA6Ly9vY3NwMDUuYWN0YWxpcy5p\n" - + "dC9WQS9BVVRILVJPT1QwHQYDVR0OBBYEFGHB5IYeTW10dLzZlzsxcXjLP5/cMA8G\n" - + "A1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbtifN7OHCUyQICNtAw\n" - + "RQYDVR0gBD4wPDA6BgRVHSAAMDIwMAYIKwYBBQUHAgEWJGh0dHBzOi8vd3d3LmFj\n" - + "dGFsaXMuaXQvYXJlYS1kb3dubG9hZDCB4wYDVR0fBIHbMIHYMIGWoIGToIGQhoGN\n" - + "bGRhcDovL2xkYXAwNS5hY3RhbGlzLml0L2NuJTNkQWN0YWxpcyUyMEF1dGhlbnRp\n" - + "Y2F0aW9uJTIwUm9vdCUyMENBLG8lM2RBY3RhbGlzJTIwUy5wLkEuJTJmMDMzNTg1\n" - + "MjA5NjcsYyUzZElUP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q7YmluYXJ5MD2g\n" - + "O6A5hjdodHRwOi8vY3JsMDUuYWN0YWxpcy5pdC9SZXBvc2l0b3J5L0FVVEgtUk9P\n" - + "VC9nZXRMYXN0Q1JMMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEA\n" - + "OD8D2Z2fw76+GIu+mDEgygH/y7F9K4I6rZOc3LqGBecO3C0fGcIuuG7APtxGGk7Y\n" - + "nk97Qt+3pDoek9EP65/1u128pRncZcjEAeMgKb7UuJxwoR6Sj5zhOadotKcCQqmF\n" - + "Si99ExNo6dTq5Eyp1KrqepLmezbO9owx4Q44mtNpfKLMgzDqOn/dwNMo/pGYbMfP\n" - + "DjhxEnta1HXgcEcgCk1Au16xkdzapwY4sXpKuwB24phfWF+cveKAQ0Rncmvrm34i\n" - + "9B6leZUkSHDe4mRkbO5nObhKHYRmVSr0Q/wvGCmTgGTKuw/Gj8+RFb5MEkOKEcJn\n" - + "I32CPohpiW/jlpeLaFBIgJnXuZTxmfTX55sqtXDlKxRxFwq1W3kML4UfGZsgjx1l\n" - + "hX5fQ1QlEZeO9CyPpgGO5Py2KXXKhUxCtF7tawAYimWwslxvPCjHDND/WhM1Fz9e\n" - + "2yqwHcSQAOUVv5mk9uYc6/NSLwLb5in3R728GNEpHHhbx5QZhtdqR8mb56uJUDKI\n" - + "AwnnZckcR+SLGL2Agx7hY7YCMOQhSsO6PA81M/mGW2hGCiZw3GULJe9ejL/vdS0I\n" - + "PWrp7YLnXUa6mtXVSBKGrVrlbpJaN10+fB4Yrlk4O2sF4WNUAHMBn9T+zOXaBAhj\n" - + "vNlMU7+elLkTcKIB7qJJuSZChxzoevM2ciO3BpGuRxg=\n" - + "-----END CERTIFICATE-----"; - - // Owner: OID.1.3.6.1.4.1.311.60.2.1.3=IT, STREET=Via S. Clemente 53, - // OID.2.5.4.15=Private Organization, CN=www.actalis.it, - // SERIALNUMBER=03358520967, O=Actalis S.p.A., L=Ponte San Pietro, ST=Bergamo, C=IT - // Issuer: CN=Actalis Extended Validation Server CA G1, - // O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // Serial number: eeeee6d6463bde2 - // Valid from: Sat Jun 17 05:59:17 PDT 2017 until: Mon Jun 17 05:59:17 PDT 2019 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" - + "MIIHwTCCBqmgAwIBAgIIDu7ubWRjveIwDQYJKoZIhvcNAQELBQAwgYcxCzAJBgNV\n" - + "BAYTAklUMQ8wDQYDVQQIDAZNaWxhbm8xDzANBgNVBAcMBk1pbGFubzEjMCEGA1UE\n" - + "CgwaQWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxMTAvBgNVBAMMKEFjdGFsaXMg\n" - + "RXh0ZW5kZWQgVmFsaWRhdGlvbiBTZXJ2ZXIgQ0EgRzEwHhcNMTcwNjE3MTI1OTE3\n" - + "WhcNMTkwNjE3MTI1OTE3WjCB0zELMAkGA1UEBhMCSVQxEDAOBgNVBAgMB0Jlcmdh\n" - + "bW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMg\n" - + "Uy5wLkEuMRQwEgYDVQQFEwswMzM1ODUyMDk2NzEXMBUGA1UEAwwOd3d3LmFjdGFs\n" - + "aXMuaXQxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRswGQYDVQQJDBJW\n" - + "aWEgUy4gQ2xlbWVudGUgNTMxEzARBgsrBgEEAYI3PAIBAxMCSVQwggEiMA0GCSqG\n" - + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwZ3++4pQYGfhXSqin1CKRJ6SOqkTcX3O0\n" - + "6b4jZbSNomyqyn6aHOz6ztOlj++fPzxmIzErEySOTd3G0pr+iwpYQVdeg1Y27KL8\n" - + "OiwwUrlV4ZMa8KKXr4BnWlDbFIo+eIcSew5V7CiodDyxpj9zjqJK497LF1jxgXtr\n" - + "IoMRwrh2Y0NbJCZGUCL30sQr/W4xBnO1+pi2DbCieGe/XoK8yEtx9FdnEFvyT9qn\n" - + "zYyrXvnTvfVSwzwtEIn+akjomI4WfCFLBF0M7v4dAHypfnPAAoW1c0BBqNB32zf0\n" - + "rYwNnD7UwZlcDihEYlgC70Dfy7bPsdq2spmOMk/VUqb3U0LHRVM3AgMBAAGjggPh\n" - + "MIID3TB9BggrBgEFBQcBAQRxMG8wOgYIKwYBBQUHMAKGLmh0dHA6Ly9jYWNlcnQu\n" - + "YWN0YWxpcy5pdC9jZXJ0cy9hY3RhbGlzLWF1dGV2ZzEwMQYIKwYBBQUHMAGGJWh0\n" - + "dHA6Ly9vY3NwMDUuYWN0YWxpcy5pdC9WQS9BVVRIRVYtRzEwHQYDVR0OBBYEFK9y\n" - + "954QoY/5XV6TayD1gWVy0gQOMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUYcHk\n" - + "hh5NbXR0vNmXOzFxeMs/n9wwUAYDVR0gBEkwRzA8BgYrgR8BEQEwMjAwBggrBgEF\n" - + "BQcCARYkaHR0cHM6Ly93d3cuYWN0YWxpcy5pdC9hcmVhLWRvd25sb2FkMAcGBWeB\n" - + "DAEBMIHvBgNVHR8EgecwgeQwgaKggZ+ggZyGgZlsZGFwOi8vbGRhcDA1LmFjdGFs\n" - + "aXMuaXQvY24lM2RBY3RhbGlzJTIwRXh0ZW5kZWQlMjBWYWxpZGF0aW9uJTIwU2Vy\n" - + "dmVyJTIwQ0ElMjBHMSxvJTNkQWN0YWxpcyUyMFMucC5BLi8wMzM1ODUyMDk2Nyxj\n" - + "JTNkSVQ/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5hcnkwPaA7oDmGN2h0\n" - + "dHA6Ly9jcmwwNS5hY3RhbGlzLml0L1JlcG9zaXRvcnkvQVVUSEVWLUcxL2dldExh\n" - + "c3RDUkwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF\n" - + "BQcDAjAZBgNVHREEEjAQgg53d3cuYWN0YWxpcy5pdDCCAX4GCisGAQQB1nkCBAIE\n" - + "ggFuBIIBagFoAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFc\n" - + "tiwHywAABAMARzBFAiEA7GC5/kja3l8cBw1/wBpHl/AKH6eL1MKpmICtf5G09c4C\n" - + "IBM887DQEwD2E4Xx/IP+33NMvUOhSwZ4XODgqFVXsz0wAHYA7ku9t3XOYLrhQmkf\n" - + "q+GeZqMPfl+wctiDAMR7iXqo/csAAAFctiwIqwAABAMARzBFAiEAwwiR95ozXdKs\n" - + "+uULfrzgENbHc2rLgGIac6ZMv0xHDLACIFLQVpvQBRQfys2KVRGHQKGxqAeghQZw\n" - + "9nJL+U5huzfaAHYA3esdK3oNT6Ygi4GtgWhwfi6OnQHVXIiNPRHEzbbsvswAAAFc\n" - + "tiwMqwAABAMARzBFAiEAifV9ocxbO6b3I22jb2zxBvG2e83hXHitOhYXkHdSmZkC\n" - + "IDJLuPvGOczF9axgphImlUbT9dX3wRpjEi5IeV+pxMiYMA0GCSqGSIb3DQEBCwUA\n" - + "A4IBAQB5U6k1Onv9Y7POHGnUOI0ATHevbpbS/7r68DZQ6cRmDIpsZyjW6PxYs9nc\n" - + "3ob3Pjomm+S7StDl9ehI7rYLlZC52QlXlsq1fzEQ9xSkf+VSD70A91dPIFAdI/jQ\n" - + "aWvIUvQEbhfUZc0ihIple0VyWGH5bza0DLW+C8ttF8KqICUfL8S8mZgjbXvVg2fY\n" - + "HLW9lWR/Pkco2yRc8gZyr9FGkXOcmJ8aFaCuJnGm/IVRCieYp60If4DoAKz49xpF\n" - + "CF6RjOAJ//UGSp/ySjHMmT8PLO7NvhsT4XDDGTSeIYYpO++tbEIcLcjW9m2k5Gnh\n" - + "kmEenr0hdcpeLgsP3Fsy7JxyQNpL\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=Actalis Authentication CA G3, O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // Issuer: CN=Actalis Authentication Root CA, O=Actalis S.p.A./03358520967, L=Milan, C=IT - // SN: 741d584a 72fc06bc - // Valid from: Wed Feb 12 22:32:23 PST 2014 - // Valid till: Mon Feb 12 22:32:23 PST 2024 - private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" - + "MIIGTTCCBDWgAwIBAgIIdB1YSnL8BrwwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\n" - + "BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w\n" - + "MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\n" - + "IENBMB4XDTE0MDIxMzE1MDIyM1oXDTI0MDIxMzE1MDIyM1owezELMAkGA1UEBhMC\n" - + "SVQxDzANBgNVBAgMBk1pbGFubzEPMA0GA1UEBwwGTWlsYW5vMSMwIQYDVQQKDBpB\n" - + "Y3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzElMCMGA1UEAwwcQWN0YWxpcyBBdXRo\n" - + "ZW50aWNhdGlvbiBDQSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n" - + "AMzhDjmhNDym6ze3PegbIKmiavXpAjgVCZ344k1DOtdSCV6k3h3rqfHqFn3mrayA\n" - + "btmJ0NeC886WxUUsJwHJ3bOnNBQZIHxLV+1RVD/6TQqb6/bPJu4rDwEfhbJSmErc\n" - + "29wUJWqxXMhSAWTHi3Pq0vrkx59e5KTEyfB2kHo6InlR72sCCRdtCL9aDuDm8nYK\n" - + "pTSAJr36ultwME5NyCNSyN2JIK0wYbEi7MVNbp5KN9MusTp3cOMDoVBreYulmnEu\n" - + "TNazmoAv0K8oLS7iX7c9x+zGjUUAucFEuSlRn3sL6hFAiKjy4PDClvnyqQHBBdZr\n" - + "/3JOxAcgXv7aZ4/STeXeDXsCAwEAAaOCAeMwggHfMEEGCCsGAQUFBwEBBDUwMzAx\n" - + "BggrBgEFBQcwAYYlaHR0cDovL3BvcnRhbC5hY3RhbGlzLml0L1ZBL0FVVEgtUk9P\n" - + "VDAdBgNVHQ4EFgQUqqr9yowdTfEug+EG/PqO6g4jrj0wDwYDVR0TAQH/BAUwAwEB\n" - + "/zAfBgNVHSMEGDAWgBRS2Ig6yJ94Zu2J83s4cJTJAgI20DBUBgNVHSAETTBLMEkG\n" - + "BFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cHM6Ly9wb3J0YWwuYWN0YWxpcy5pdC9S\n" - + "ZXBvc2l0b3J5L1BvbGljeS9TU0wvQ1BTMIHiBgNVHR8EgdowgdcwgZSggZGggY6G\n" - + "gYtsZGFwOi8vbGRhcC5hY3RhbGlzLml0L2NuJTNkQWN0YWxpcyUyMEF1dGhlbnRp\n" - + "Y2F0aW9uJTIwUm9vdCUyMENBLG8lM2RBY3RhbGlzJTIwUy5wLkEuJTJmMDMzNTg1\n" - + "MjA5NjcsYyUzZElUP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q7YmluYXJ5MD6g\n" - + "PKA6hjhodHRwOi8vcG9ydGFsLmFjdGFsaXMuaXQvUmVwb3NpdG9yeS9BVVRILVJP\n" - + "T1QvZ2V0TGFzdENSTDAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIB\n" - + "ABP93l+9QBgzHF0Clf3gMAelGqwXT25DwZVFIkBw6YyqOPcaqzw1XKHJJEMQ8xOp\n" - + "8uuiPLP/ObxEXBBvH7ofNW7nRUIzGsuLPhzdfJhdzilCVAvz4WRsX44nWOQS4Qu0\n" - + "npo7dbq/KxFUCUO9yNEJp6YxNloy8XFIlazkHFTKGJqoUpsGoc7B9YmPchhE2FPb\n" - + "OZiOCg4Y2Qp43UJfnENgZ3gJFh16juQE1uS8Q/JJI7ZzJfJ/W0uQoDnCprOPUpLF\n" - + "G03e0asFxwQqhL84Jvf7rJZaWvwydHP4hH47nzpHWEGXwfJLXXoO7LHgqVB7K9Ar\n" - + "Zf3pY0S/3Fs+AN/PrEY3Z3rb7ypQLRiot1oJLl8matiGEF4aFL5DDkr9wfRAZ8S8\n" - + "WT69vN68ENGgEwyeZSlQxn+4g6quHRav0fmF2fGnLaq7tteSPVocT7XaMEpkHqNs\n" - + "x1q/PJbr39s/1QVZtS9CrdoCr0QAnBaX//PPB6ansSLFcvEqM9QcV9xQZex88ToX\n" - + "nk3TcHtA0ezWJlCkg626MhdQZrhHbkauHfIGSOmCkn3zHp0BZQ6Vo7UOdRMT7QS7\n" - + "y7AkET9Qmapwh2CFUdCJSXklVRd+06XhhOB37NQU0pGJQJ3xjEPrILZ8kLhW3Tyq\n" - + "Iv30LW7MXZ4yQn/JHEZbuiOOb4R45hsPZxe6gOq/e+sf\n" - + "-----END CERTIFICATE-----"; - - // Owner: CN=ssltest-r.actalis.it, O=Actalis S.p.A., L=Ponte San Pietro, ST=Bergamo, C=IT - // Issuer: CN=Actalis Authentication CA G3, O=Actalis S.p.A./03358520967, L=Milano, ST=Milano, C=IT - // SN: 0455de97 5c71c96f - // Valid from: Thu Jan 28 16:23:52 PST 2016 - // Valid till: Mon Jan 28 16:23:52 PST 2019 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" - + "MIIFmDCCBICgAwIBAgIIBFXel1xxyW8wDQYJKoZIhvcNAQELBQAwezELMAkGA1UE\n" - + "BhMCSVQxDzANBgNVBAgMBk1pbGFubzEPMA0GA1UEBwwGTWlsYW5vMSMwIQYDVQQK\n" - + "DBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzElMCMGA1UEAwwcQWN0YWxpcyBB\n" - + "dXRoZW50aWNhdGlvbiBDQSBHMzAeFw0xNjAxMjkwODUzNTJaFw0xOTAxMjkwODUz\n" - + "NTJaMHIxCzAJBgNVBAYTAklUMRAwDgYDVQQIDAdCZXJnYW1vMRkwFwYDVQQHDBBQ\n" - + "b250ZSBTYW4gUGlldHJvMRcwFQYDVQQKDA5BY3RhbGlzIFMucC5BLjEdMBsGA1UE\n" - + "AwwUc3NsdGVzdC1yLmFjdGFsaXMuaXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\n" - + "ggEKAoIBAQClbzoXCvD21FD7Oy/TKZu4fmDFJrISrNfasLlC3krLHkgb1vg23Z1P\n" - + "+7rIymDgrJSzjvYmisl+VM7xXxTsyI2pp9Qp/uzTMAMML9ISd/s0LaMBiNN5iPyj\n" - + "W91gGzGe30Jc319afKwFBaveSv7NO3DWsmHw9koezWkKUug2dnQCVXk1uTSdobnq\n" - + "wOgwxdd86LpZnFLxBIYdU68S4vogAQZjdja/S1+tF6JnfvY6o/xRJmQckVtNmUs6\n" - + "Dj3KoN2o/8BEgSCYcJz8tfoZcVazVkWOp/u6moUnm1/IKSYNgtHnB1ub0fB2AttW\n" - + "Vi7cs3SG/tDMMP8yc1kWScWf8CYj/AI1AgMBAAGjggInMIICIzA/BggrBgEFBQcB\n" - + "AQQzMDEwLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwMDMuYWN0YWxpcy5pdC9WQS9B\n" - + "VVRILUczMB0GA1UdDgQWBBRIKN5WmrjivlnT1rDzsH1WZ+PuvTAMBgNVHRMBAf8E\n" - + "AjAAMB8GA1UdIwQYMBaAFKqq/cqMHU3xLoPhBvz6juoOI649MGAGA1UdIARZMFcw\n" - + "SwYGK4EfARQBMEEwPwYIKwYBBQUHAgEWM2h0dHBzOi8vcG9ydGFsLmFjdGFsaXMu\n" - + "aXQvUmVwb3NpdG9yeS9Qb2xpY3kvU1NML0NQUzAIBgZngQwBAgIwgd8GA1UdHwSB\n" - + "1zCB1DCBlKCBkaCBjoaBi2xkYXA6Ly9sZGFwMDMuYWN0YWxpcy5pdC9jbiUzZEFj\n" - + "dGFsaXMlMjBBdXRoZW50aWNhdGlvbiUyMENBJTIwRzMsbyUzZEFjdGFsaXMlMjBT\n" - + "LnAuQS4lMmYwMzM1ODUyMDk2NyxjJTNkSVQ/Y2VydGlmaWNhdGVSZXZvY2F0aW9u\n" - + "TGlzdDtiaW5hcnkwO6A5oDeGNWh0dHA6Ly9jcmwwMy5hY3RhbGlzLml0L1JlcG9z\n" - + "aXRvcnkvQVVUSC1HMy9nZXRMYXN0Q1JMMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE\n" - + "FjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0RBBgwFoIUc3NsdGVzdC1yLmFj\n" - + "dGFsaXMuaXQwDQYJKoZIhvcNAQELBQADggEBAHZLND53/CZoMlDtfln0ZByCEhoF\n" - + "/XtA9cYy2azRGgS/VY4WUccvg99MM50cwn5GPRsJpoaFXeDrjV3DkOUK1jERzjx4\n" - + "5y83K/AkCGe7uU17aS+tweETizBAfHNj78oHmZDmkDSEY2STaeuHNDJ9ft0v3QTb\n" - + "VW54R5W3OBU7L/sJoEUdRxzGN7vO82PboGvyApMCWDRLKE7bPP4genQtF3XPcaFl\n" - + "ekuSiEVYS+KnM2v9tCWHqw6x7raWHFB9w1kAKNwv0hbEJkeC+a2bCdPwv8hs//sa\n" - + "gUF4p61mIpf+5qmQ6gcZOClPWyrbYdQdfCvKgbEdKhwB0v5KS0NIRRn41SE=\n" - + "-----END CERTIFICATE-----"; + // Owner: CN=Actalis Organization Validated Server CA G3, O=Actalis S.p.A., + // L=Ponte San Pietro, ST=Bergamo, C=IT + // Issuer: CN=Actalis Authentication Root CA, O=Actalis S.p.A ./03358520967, + // L=Milan, C=IT + // Serial number: 5c3b3f37adfc28fe0fcfd3abf83f8551 + // Valid from: Mon Jul 06 00:20:55 PDT 2020 until: Sun Sep 22 04:22:02 PDT 2030 + private static final String INT = "-----BEGIN CERTIFICATE-----\n" + + "MIIHdTCCBV2gAwIBAgIQXDs/N638KP4Pz9Or+D+FUTANBgkqhkiG9w0BAQsFADBr\n" + + "MQswCQYDVQQGEwJJVDEOMAwGA1UEBwwFTWlsYW4xIzAhBgNVBAoMGkFjdGFsaXMg\n" + + "Uy5wLkEuLzAzMzU4NTIwOTY3MScwJQYDVQQDDB5BY3RhbGlzIEF1dGhlbnRpY2F0\n" + + "aW9uIFJvb3QgQ0EwHhcNMjAwNzA2MDcyMDU1WhcNMzAwOTIyMTEyMjAyWjCBiTEL\n" + + "MAkGA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNh\n" + + "biBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMTQwMgYDVQQDDCtBY3Rh\n" + + "bGlzIE9yZ2FuaXphdGlvbiBWYWxpZGF0ZWQgU2VydmVyIENBIEczMIICIjANBgkq\n" + + "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs73Ch+t2owm3ayTkyqy0OPuCTiybxTyS\n" + + "4cU4y0t2RGSwCNjLh/rcutO0yoriZxVtPrNMcIRQ544BQhHFt/ypW7e+t8wWKrHa\n" + + "r3BkKwSUbqNwpDWP1bXs7IJTVhHXWGAm7Ak1FhrrBmtXk8QtdzTzDDuxfFBK7sCL\n" + + "N0Jdqoqb1V1z3wsWqAvr4KlSCFW05Nh4baWm/kXOmb8U+XR6kUmuoVvia3iBhotR\n" + + "TzAHTO9SWWkgjTcir/nhBvyL2RoqkgYyP/k50bznaVOGFnFWzfl0XnrM/salfCBh\n" + + "O0/1vNaoU8elR6AtbdCFAupgQy95GuFIRVS8n/cF0QupfPjUl+kGSLzvGAc+6oNE\n" + + "alpAhKIS/+P0uODzRrS9Eq0WX1iSj6KHtQMNN4ZKsS4nsuvYCahnAc0QwQyoduAW\n" + + "iU/ynhU9WTIEe1VIoEDE79NPOI2/80RqbZqdpAKUaf0FvuqVXhEcjiJJu+d0w9YN\n" + + "b7gurd6xkaSXemW/fP4idBiNkd8aCVAdshGQYn6yh+na0Lu5IG88Z2kSIFcXDtwy\n" + + "zjcxkW86pwkO6GekEomVBNKcv0Cey2Smf8uhpZk15TSCeyFDrZBWH9OsDst/Tnhz\n" + + "pN156Huw3M3RRdEegt33fcyPykgt0HThxrEv9DwOzhs6lCQ5RNQJO7ZvZF1ZiqgT\n" + + "FOJ6vs1xMqECAwEAAaOCAfQwggHwMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw\n" + + "FoAUUtiIOsifeGbtifN7OHCUyQICNtAwQQYIKwYBBQUHAQEENTAzMDEGCCsGAQUF\n" + + "BzABhiVodHRwOi8vb2NzcDA1LmFjdGFsaXMuaXQvVkEvQVVUSC1ST09UMEUGA1Ud\n" + + "IAQ+MDwwOgYEVR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hY3RhbGlz\n" + + "Lml0L2FyZWEtZG93bmxvYWQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB\n" + + "MIHjBgNVHR8EgdswgdgwgZaggZOggZCGgY1sZGFwOi8vbGRhcDA1LmFjdGFsaXMu\n" + + "aXQvY24lM2RBY3RhbGlzJTIwQXV0aGVudGljYXRpb24lMjBSb290JTIwQ0EsbyUz\n" + + "ZEFjdGFsaXMlMjBTLnAuQS4lMmYwMzM1ODUyMDk2NyxjJTNkSVQ/Y2VydGlmaWNh\n" + + "dGVSZXZvY2F0aW9uTGlzdDtiaW5hcnkwPaA7oDmGN2h0dHA6Ly9jcmwwNS5hY3Rh\n" + + "bGlzLml0L1JlcG9zaXRvcnkvQVVUSC1ST09UL2dldExhc3RDUkwwHQYDVR0OBBYE\n" + + "FJ+KsbXxsd6C9Cd8vojN3qlDgaNLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0B\n" + + "AQsFAAOCAgEAJbygMnKJ5M6byr5Ectq05ODqwNMtky8TEF3O55g6RHhxblf6OegZ\n" + + "4ui4+ElHNOIXjycbeuUGuFA4LScCC9fnI1Rnn8TI2Q7OP5YWifEfnrdp99t/tJzQ\n" + + "hfdi7ZTdRRZZGV9x+grfR/RtjT2C3Lt9X4lcbuSxTea3PHAwwi0A3bYRR1L5ciPm\n" + + "eAnYtG9kpat8/RuC22oxiZZ5FdjU6wrRWkASRLiIwNcFIYfvpUbMWElaCUhqaB2y\n" + + "YvWF8o02pnaYb4bvTCg4cVabVnojUuuXH81LeQhhsSXLwcdwSdew0NL4zCiNCn2Q\n" + + "iDZpz2biCWDggibmWxsUUF6AbqMHnwsdS8vsKXiFQJHeAdNAhA+kwpqYAdhUiCdj\n" + + "RTUdtRNUucLvZEN1OAvVYyog9xYCfhtkqgXQROMANP+Z/+yaZahaP/Vgak/V00se\n" + + "Hdh7F+B6h5HVdwdh+17E2jl+aMTfyvBFcg2H/9Qjyl4TY8NW/6v0DPK52sVt8a35\n" + + "I+7xLGLPohAl4z6pEf2OxgjMNfXXCXS33smRgz1dLQFo8UpAb3rf84zkXaqEI6Qi\n" + + "2P+5pibVFQigRbn4RcE+K2a/nm2M/o+WZTSio+E+YXacnNk71VcO82biOof+jBKT\n" + + "iC3Xi7rAlypmme+QFBw9F1J89ig3smV/HaN8tO0lfTpvm7Zvzd5TkMs=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=ssltest-active.actalis.it, O=Actalis S.p.A., L=Ponte San Pietro, + // ST=Bergamo, C=IT + // Issuer: CN=Actalis Organization Validated Server CA G3, O=Actalis S.p A., + // L=Ponte San Pietro, ST=Bergamo, C=IT + // Serial number: 4a49e2afcd448af3b7f5f14e1cd5954 + // Valid from: Tue Mar 08 08:00:57 PST 2022 until: Wed Mar 08 08:00:57 PST 2023 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIH0jCCBbqgAwIBAgIQBKSeKvzUSK87f18U4c1ZVDANBgkqhkiG9w0BAQsFADCB\n" + + "iTELMAkGA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRl\n" + + "IFNhbiBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMTQwMgYDVQQDDCtB\n" + + "Y3RhbGlzIE9yZ2FuaXphdGlvbiBWYWxpZGF0ZWQgU2VydmVyIENBIEczMB4XDTIy\n" + + "MDMwODE2MDA1N1oXDTIzMDMwODE2MDA1N1owdzELMAkGA1UEBhMCSVQxEDAOBgNV\n" + + "BAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQaWV0cm8xFzAVBgNVBAoM\n" + + "DkFjdGFsaXMgUy5wLkEuMSIwIAYDVQQDDBlzc2x0ZXN0LWFjdGl2ZS5hY3RhbGlz\n" + + "Lml0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsJnlOatNNth7gfqZ\n" + + "WN8HMfp9qlkDf/YW8ReNXyTtqFEy2xZrVVmAV2XIqL1lJDYJz86mdVsz3AqIMTzo\n" + + "GxPlmn/oEnF0YeRYQ1coKRdwP7hWSwqyMMhh+C7r5zMA9gQQVXV5wWR5U+bgvt23\n" + + "Y/55DOqk3Fp5Odt6Lyu6xA45MwHrj2Gr/nMKe8L7f8UYPWT98MJa1+TXB24yllOw\n" + + "rZE8gZByLBCVzDkVwRwTgu+HgY6zm5sJTvBT4tyJy4QD8u2xLWoZ5sXodrU0Z3Nf\n" + + "xU9keMFp6CIh1t+akqFgpW81b/HWkfUO0+L6PH4hgaSPtiwp2dVFsF9v5p4on9qA\n" + + "2j1d9QIDAQABo4IDRTCCA0EwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSfirG1\n" + + "8bHegvQnfL6Izd6pQ4GjSzB+BggrBgEFBQcBAQRyMHAwOwYIKwYBBQUHMAKGL2h0\n" + + "dHA6Ly9jYWNlcnQuYWN0YWxpcy5pdC9jZXJ0cy9hY3RhbGlzLWF1dGhvdmczMDEG\n" + + "CCsGAQUFBzABhiVodHRwOi8vb2NzcDA5LmFjdGFsaXMuaXQvVkEvQVVUSE9WLUcz\n" + + "MCQGA1UdEQQdMBuCGXNzbHRlc3QtYWN0aXZlLmFjdGFsaXMuaXQwUQYDVR0gBEow\n" + + "SDA8BgYrgR8BFAEwMjAwBggrBgEFBQcCARYkaHR0cHM6Ly93d3cuYWN0YWxpcy5p\n" + + "dC9hcmVhLWRvd25sb2FkMAgGBmeBDAECAjAdBgNVHSUEFjAUBggrBgEFBQcDAgYI\n" + + "KwYBBQUHAwEwSAYDVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDA5LmFjdGFsaXMu\n" + + "aXQvUmVwb3NpdG9yeS9BVVRIT1YtRzMvZ2V0TGFzdENSTDAdBgNVHQ4EFgQUIbcm\n" + + "54DVM6gC8DYhvnZg8ILaLrAwDgYDVR0PAQH/BAQDAgWgMIIBfQYKKwYBBAHWeQIE\n" + + "AgSCAW0EggFpAWcAdQCt9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAA\n" + + "AX9qTFEkAAAEAwBGMEQCIFB4RW+Fca/jj96sFg9JtZVe/CAQq74HAezTi2AD07qL\n" + + "AiBej8APns5uKmaHNYbU6lel6kdowIaUY/+iqX82e2KhrAB2AOg+0No+9QY1MudX\n" + + "KLyJa8kD08vREWvs62nhd31tBr1uAAABf2pMUVMAAAQDAEcwRQIgcopYpSUDiQ2C\n" + + "7j06vgbfsn3ux4REvpbrbWatifLtfVMCIQCi96i+4EhAUOw4dumA7hJwlG+qD/+5\n" + + "uSL3aKB9KR7apAB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAAB\n" + + "f2pMUYEAAAQDAEcwRQIgdCNjaV7nQcCiVefX28u1vtQMy+rqT4F4i9EVJ2xbqbQC\n" + + "IQCrpcYqt53tX/rSMoGnjFhDGnMhnYyc2AqzpokfhmdcVTANBgkqhkiG9w0BAQsF\n" + + "AAOCAgEAfXISBKP1dZQv1kkWZVDXiVY/fv+068DKq2e8hgBcsN6b9a2rlVfBU2iq\n" + + "W9KqFNET5GDWf1wjM71Itjau8b1A3+apcNdEGQk3eqIOymK5kVtVvAI2ahp4926x\n" + + "Kkt/sexmi1pJGA+eLfTixkCoaESh5P8U7HDW/vUFXm2AtLQih+oT5OVoYt5e9pXr\n" + + "hr8oadm/ZDJxiyDL1vcTIsl2TM4/Fpo2IWxYzUC+YshnuLiRwWI840maJmWFx/lJ\n" + + "Pzdik3P51Uef7VsCSBhTxER09/B4IrEUMDAhVgG5QNbcFSHvnmpV8JLrNuBKUROU\n" + + "xnDsWieKlb5YO6S6PjGOncOrd+k4RCIYRaekSnx52WBKkpqxMEv/rjY1Glx4Cota\n" + + "mpNiYDvZHGzrRQtY2eH17XhFatBxEEbJMA+0QPbFksHcKxAxJgMDncqag4TDq5fT\n" + + "I2NUxqiB51F5w0x+++lyLnUZ+z4BJFZ73VdtfoJ2fsuRhemOoZjHPi/V2exXpAfb\n" + + "pomha3KCrTcuFv1lj8mPx5L4ciNPxuDFgjeXEaTGjS8IvdNoJIrgdHdahMwkwS/y\n" + + "wei7FJ1Ey0maqRUpUlAY6sIQPQ/KDltTuKX/C94C5pYLI0JXCScr5xg6C+r2ckbA\n" + + "rjhpn3C/NptVyZgT8bL4XT5ITrAjwPciBj0yxYzUkrLZO1wKQSQ=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=ssltest-revoked.actalis.it, O=Actalis S.p.A., L=Ponte San Pietro, ST=Bergamo, C=IT + // Issuer: CN=Actalis Organization Validated Server CA G3, O=Actalis S.p.A., + // L=Ponte San Pietro, ST=Bergamo, C=IT + // Serial number: 320955171b78d49507508910da2c5bc4 + // Valid from: Tue Sep 27 03:40:43 PDT 2022 until: Wed Sep 27 03:40:43 PDT 2023 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIH1TCCBb2gAwIBAgIQMglVFxt41JUHUIkQ2ixbxDANBgkqhkiG9w0BAQsFADCB\n" + + "iTELMAkGA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRl\n" + + "IFNhbiBQaWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMTQwMgYDVQQDDCtB\n" + + "Y3RhbGlzIE9yZ2FuaXphdGlvbiBWYWxpZGF0ZWQgU2VydmVyIENBIEczMB4XDTIy\n" + + "MDkyNzEwNDA0M1oXDTIzMDkyNzEwNDA0M1oweDELMAkGA1UEBhMCSVQxEDAOBgNV\n" + + "BAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQaWV0cm8xFzAVBgNVBAoM\n" + + "DkFjdGFsaXMgUy5wLkEuMSMwIQYDVQQDDBpzc2x0ZXN0LXJldm9rZWQuYWN0YWxp\n" + + "cy5pdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdBnbeFtw/Ejp1U\n" + + "gr86BQ5rqgGXWWXb7fsOhPb5On9RXTojg6oaeIV4GxHsMZhEDKQdcZ6JWAo2dbtp\n" + + "/7ereFEDWG/YJahLHFZ/ihXG4AmfObYEhoGbKitW75fOs/aWC7Veck/sXsw7cjLW\n" + + "GY623ybcF9DBExg3S4uLRaSkv5hXUDu/CzphUgwiEd5YNBZjcryOiS8+Y5EQ+2q+\n" + + "g+tdRG9m5G5YxeHWgQz2HDDwLDsJhWkb8/RsUurU/I+avHPhYk13K5Ysf311gww8\n" + + "bAsplfdJ2gdn8Is+EAEH4GJHqMybC95YDh1w5dY7dk/lIoNX4hYUIQimirIr3OW8\n" + + "Svkj1G8CAwEAAaOCA0cwggNDMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUn4qx\n" + + "tfGx3oL0J3y+iM3eqUOBo0swfgYIKwYBBQUHAQEEcjBwMDsGCCsGAQUFBzAChi9o\n" + + "dHRwOi8vY2FjZXJ0LmFjdGFsaXMuaXQvY2VydHMvYWN0YWxpcy1hdXRob3ZnMzAx\n" + + "BggrBgEFBQcwAYYlaHR0cDovL29jc3AwOS5hY3RhbGlzLml0L1ZBL0FVVEhPVi1H\n" + + "MzAlBgNVHREEHjAcghpzc2x0ZXN0LXJldm9rZWQuYWN0YWxpcy5pdDBRBgNVHSAE\n" + + "SjBIMDwGBiuBHwEUATAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hY3RhbGlz\n" + + "Lml0L2FyZWEtZG93bmxvYWQwCAYGZ4EMAQICMB0GA1UdJQQWMBQGCCsGAQUFBwMC\n" + + "BggrBgEFBQcDATBIBgNVHR8EQTA/MD2gO6A5hjdodHRwOi8vY3JsMDkuYWN0YWxp\n" + + "cy5pdC9SZXBvc2l0b3J5L0FVVEhPVi1HMy9nZXRMYXN0Q1JMMB0GA1UdDgQWBBS6\n" + + "o8qJpg3ixoyA2QBayptaTfc+5DAOBgNVHQ8BAf8EBAMCBaAwggF+BgorBgEEAdZ5\n" + + "AgQCBIIBbgSCAWoBaAB2AK33vvp8/xDIi509nB4+GGq0Zyldz7EMJMqFhjTr3IKK\n" + + "AAABg36SGRYAAAQDAEcwRQIgDXxSCQGfcIYroxNiDJg08IX38Y9+r5CC6T4NeW14\n" + + "FzgCIQDdEhEYsGIWpwyrnTLr4RFB5CMEq+84dByNT07UYkiVwwB2AHoyjFTYty22\n" + + "IOo44FIe6YQWcDIThU070ivBOlejUutSAAABg36SGTUAAAQDAEcwRQIgL2ig9RrM\n" + + "FPWESGRYGJJJYRHdcayHev66jawrf98saN8CIQD/CInlI3Vo7SBzzN/4uykjYsFZ\n" + + "u9RypT6AYv6AHPlNdQB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kT\n" + + "AAABg36SGU0AAAQDAEcwRQIhAOCD/dOs4HjyC+GQaQRh4U+/mUwWyu+CnlHdebmD\n" + + "hAvFAiAvBE0rbxgm8TpZLG2TaMk3dqZj7Q6FFdLlqTsvwhKa3jANBgkqhkiG9w0B\n" + + "AQsFAAOCAgEAEnPALMVp1pySJgHhugLWAUgiD6stpDWCKfaBxPr+jf34A5wS+m5r\n" + + "2VhYyNQpOwIQB76K2RSJQrdpg7Dg2L6EiUnbbClSTrOkZ4XX5ggBIjldDEx4ZxhI\n" + + "zwSw4KB6+DDAVMwsCL0q0E7AAPOMaZ0RDLteusqQYIYm08TXfJPWD8LjQPt/8Uie\n" + + "LOqm1eLUuwJc+eHFWV+Xr8Uea6SFwqNEj7qPHb2MElctET/MhSIIUKI1ObmrFwyB\n" + + "ElKEPaUh9L0HXpnuD8IWc7tw2mdvnWJhuGG8G6JkasTGvtZ4gKIDBdTrJcuj7MCS\n" + + "amz3ZBCY47tP1ohgImjqwg4ITYjX6UQXgj/nBVDdu+nXkEhx16uPJkTYWaun9Nio\n" + + "8RjYIOxXmDD39QbGUElP0Epsr2wcVT9tIFYMGzUpIO51mCk3Aq1AmiQZwZZhqOIN\n" + + "RDx7lGESPj3IgdVfJi9Ing/OUNtS46Ug9DSuDcGqdY7KnTYEUdWGsUJNtnpjd4lS\n" + + "U6oIAeW1aKuOve6iNg1vsFAN57aJNh1ih3BOup58J9ve42bNlAYWN8wiNxM+Aeba\n" + + "ArUSTnH/QEYCyMRD0XqIREVR9VhNODgSZbL3XedYBAW9wImi1whp+u+8aReXd7lC\n" + + "Q3kD9KRyfZ9Kk05Glf3DsZMWvp1N2ZZWaU2Ms5U3ijUheCiBrqrs8a8=\n" + + "-----END CERTIFICATE-----"; public static void main(String[] args) throws Exception { ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - boolean ocspEnabled = false; if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { pathValidator.enableCRLCheck(); } else { // OCSP check by default pathValidator.enableOCSPCheck(); - ocspEnabled = true; } // Validate valid - pathValidator.validate(new String[]{VALID, INT_VALID}, + pathValidator.validate(new String[]{VALID, INT}, ValidatePathWithParams.Status.GOOD, null, System.out); - // Revoked certificate is using SHA1 signature - if (ocspEnabled) { - // Revoked test certificate is expired - // and backdated revocation check is only possible with OCSP - pathValidator.setValidationDate("July 01, 2016"); - } - // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, + pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Fri Jan 29 01:06:42 PST 2016", System.out); - - // reset validation date back to current date - pathValidator.resetValidationDate(); + "Tue Sep 27 03:52:40 PDT 2022", System.out); } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java --- openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * 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,291 +51,325 @@ public static void main(String[] args) throws Exception { ValidatePathWithParams pathValidator = new ValidatePathWithParams(null); - boolean ocspEnabled = false; if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { pathValidator.enableCRLCheck(); } else { // OCSP check by default pathValidator.enableOCSPCheck(); - ocspEnabled = true; } - new AmazonCA_1().runTest(pathValidator, ocspEnabled); - new AmazonCA_2().runTest(pathValidator, ocspEnabled); - new AmazonCA_3().runTest(pathValidator, ocspEnabled); - new AmazonCA_4().runTest(pathValidator, ocspEnabled); + new AmazonCA_1().runTest(pathValidator); + new AmazonCA_2().runTest(pathValidator); + new AmazonCA_3().runTest(pathValidator); + new AmazonCA_4().runTest(pathValidator); } } class AmazonCA_1 { - // Owner: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US + // Owner: CN=Amazon RSA 2048 M02, O=Amazon, C=US // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US - // Serial number: 67f9457508c648c09ca652e71791830e72592 - // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIERzCCAy+gAwIBAgITBn+UV1CMZIwJymUucXkYMOclkjANBgkqhkiG9w0BAQsF\n" + + // Serial number: 773124a4bcbd44ec7b53beaf194842d3a0fa1 + // Valid from: Tue Aug 23 15:25:30 PDT 2022 until: Fri Aug 23 15:25:30 PDT 2030 + private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIEXjCCA0agAwIBAgITB3MSSkvL1E7HtTvq8ZSELToPoTANBgkqhkiG9w0BAQsF\n" + + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + + "b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjUzMFoXDTMwMDgyMzIyMjUzMFowPDEL\n" + + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n" + + "QSAyMDQ4IE0wMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALtDGMZa\n" + + "qHneKei1by6+pUPPLljTB143Si6VpEWPc6mSkFhZb/6qrkZyoHlQLbDYnI2D7hD0\n" + + "sdzEqfnuAjIsuXQLG3A8TvX6V3oFNBFVe8NlLJHvBseKY88saLwufxkZVwk74g4n\n" + + "WlNMXzla9Y5F3wwRHwMVH443xGz6UtGSZSqQ94eFx5X7Tlqt8whi8qCaKdZ5rNak\n" + + "+r9nUThOeClqFd4oXych//Rc7Y0eX1KNWHYSI1Nk31mYgiK3JvH063g+K9tHA63Z\n" + + "eTgKgndlh+WI+zv7i44HepRZjA1FYwYZ9Vv/9UkC5Yz8/yU65fgjaE+wVHM4e/Yy\n" + + "C2osrPWE7gJ+dXMCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\n" + + "VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV\n" + + "HQ4EFgQUwDFSzVpQw4J8dHHOy+mc+XrrguIwHwYDVR0jBBgwFoAUhBjMhTTsvAyU\n" + + "lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v\n" + + "b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov\n" + + "L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E\n" + + "ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv\n" + + "b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB\n" + + "AQAtTi6Fs0Azfi+iwm7jrz+CSxHH+uHl7Law3MQSXVtR8RV53PtR6r/6gNpqlzdo\n" + + "Zq4FKbADi1v9Bun8RY8D51uedRfjsbeodizeBB8nXmeyD33Ep7VATj4ozcd31YFV\n" + + "fgRhvTSxNrrTlNpWkUk0m3BMPv8sg381HhA6uEYokE5q9uws/3YkKqRiEz3TsaWm\n" + + "JqIRZhMbgAfp7O7FUwFIb7UIspogZSKxPIWJpxiPo3TcBambbVtQOcNRWz5qCQdD\n" + + "slI2yayq0n2TXoHyNCLEH8rpsJRVILFsg0jc7BaFrMnF462+ajSehgj12IidNeRN\n" + + "4zl+EoNaWdpnWndvSpAEkq2P\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Amazon RSA 2048 M01, O=Amazon, C=US + // Issuer: CN=Amazon Root CA 1, O=Amazon, C=US + // Serial number: 77312380b9d6688a33b1ed9bf9ccda68e0e0f + // Valid from: Tue Aug 23 15:21:28 PDT 2022 until: Fri Aug 23 15:21:28 PDT 2030 + private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIEXjCCA0agAwIBAgITB3MSOAudZoijOx7Zv5zNpo4ODzANBgkqhkiG9w0BAQsF\n" + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + - "b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" + - "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" + - "IDFBMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" + - "AoIBAQCeQM3XCsIZunv8bSJxOqkc/ed87uL76FDB7teBNThDRB+1J7aITuadbNfH\n" + - "5ZfZykrdZ1qQLKxP6DwHOmJr9u2b4IxjUX9qUMuq4B02ghD2g6yU3YivEosZ7fpo\n" + - "srD2TBN29JpgPGrOrpOE+ArZuIpBjdKFinemu6fTDD0NCeQlfyHXd1NOYyfYRLTa\n" + - "xlpDqr/2M41BgSkWQfSPHHyRWNQgWBiGsIQaS8TK0g8OWi1ov78+2K9DWT+AHgXW\n" + - "AanjZK91GfygPXJYSlAGxSiBAwH/KhAMifhaoFYAbH0Yuohmd85B45G2xVsop4TM\n" + - "Dsl007U7qnS7sdJ4jYGzEvva/a95AgMBAAGjggE5MIIBNTASBgNVHRMBAf8ECDAG\n" + - "AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUYtRCXoZwdWqQvMa40k1g\n" + - "wjS6UTowHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH\n" + - "AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy\n" + - "dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy\n" + - "dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js\n" + - "LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBEGA1UdIAQKMAgw\n" + - "BgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEAMHbSWHRFMzGNIE0qhN6gnRahTrTU\n" + - "CDPwe7l9/q0IA+QBlrpUHnlAreetYeH1jB8uF3qXXzy22gpBU7NqulTkqSPByT1J\n" + - "xOhpT2FpO5R3VAdMPdWfSEgtrED0jkmyUQrR1T+/A+nBLdJZeQcl+OqLgeY790JM\n" + - "JJTsJnnI6FBWeTGhcDI4Y+n3KS3QCVePeWI7jx1dhrHcXH+QDX8Ywe31hV7YENdr\n" + - "HDpUXrjK6eHN8gazy8G6pndXHFwHp4auiZbJbYAk/q1peOTRagD2JojcLkm+i3cD\n" + - "843t4By6YT/PVlePU2PCWejkrJQnKQAPOov7IA8kuO2RDWuzE/zF6Hotdg==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US - // Serial number: 703e4e4bbd78e2b6db5634f36c4ee944cb1a4 - // Valid from: Mon Jul 29 16:53:36 PDT 2019 until: Sat Aug 29 16:53:36 PDT 2020 + "b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjEyOFoXDTMwMDgyMzIyMjEyOFowPDEL\n" + + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n" + + "QSAyMDQ4IE0wMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOtxLKnL\n" + + "H4gokjIwr4pXD3i3NyWVVYesZ1yX0yLI2qIUZ2t88Gfa4gMqs1YSXca1R/lnCKeT\n" + + "epWSGA+0+fkQNpp/L4C2T7oTTsddUx7g3ZYzByDTlrwS5HRQQqEFE3O1T5tEJP4t\n" + + "f+28IoXsNiEzl3UGzicYgtzj2cWCB41eJgEmJmcf2T8TzzK6a614ZPyq/w4CPAff\n" + + "nAV4coz96nW3AyiE2uhuB4zQUIXvgVSycW7sbWLvj5TDXunEpNCRwC4kkZjK7rol\n" + + "jtT2cbb7W2s4Bkg3R42G3PLqBvt2N32e/0JOTViCk8/iccJ4sXqrS1uUN4iB5Nmv\n" + + "JK74csVl+0u0UecCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\n" + + "VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV\n" + + "HQ4EFgQUgbgOY4qJEhjl+js7UJWf5uWQE4UwHwYDVR0jBBgwFoAUhBjMhTTsvAyU\n" + + "lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v\n" + + "b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov\n" + + "L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E\n" + + "ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv\n" + + "b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB\n" + + "AQCtAN4CBSMuBjJitGuxlBbkEUDeK/pZwTXv4KqPK0G50fOHOQAd8j21p0cMBgbG\n" + + "kfMHVwLU7b0XwZCav0h1ogdPMN1KakK1DT0VwA/+hFvGPJnMV1Kx2G4S1ZaSk0uU\n" + + "5QfoiYIIano01J5k4T2HapKQmmOhS/iPtuo00wW+IMLeBuKMn3OLn005hcrOGTad\n" + + "hcmeyfhQP7Z+iKHvyoQGi1C0ClymHETx/chhQGDyYSWqB/THwnN15AwLQo0E5V9E\n" + + "SJlbe4mBlqeInUsNYugExNf+tOiybcrswBy8OFsd34XOW3rjSUtsuafd9AWySa3h\n" + + "xRRrwszrzX/WWGm6wyB+f7C4\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=valid.rootca1.demo.amazontrust.com + // Issuer: CN=Amazon RSA 2048 M02, O=Amazon, C=US + // Serial number: 60c6e837b2e7586d8464eb34f4a85fe + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIFEzCCA/ugAwIBAgITBwPk5LvXjitttWNPNsTulEyxpDANBgkqhkiG9w0BAQsF\n" + - "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + - "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzUzMzZaFw0yMDA4\n" + - "MjkyMzUzMzZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + - "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" + - "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" + - "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" + - "czEjMCEGA1UEAxMaZ29vZC5zY2ExYS5hbWF6b250cnVzdC5jb20wggEiMA0GCSqG\n" + - "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQyuJ83c2Zf9k29f6iLqd8nJSuHSk1v+SS\n" + - "0sYyG8tjscfCC1HcOdNj37vtiNN65sXh/e/kBKH9wvzhCLOJbBqVKRHOZuHdJEpH\n" + - "35R6C/PbcV/tp49g6mNmBe+lcmm/cwwCtYvkL0rgL/OKB0liFhhRIqy2TPg08op/\n" + - "RlY2DdbgBA2B3g7wdMo0hK3SO56/QUccUtLRm43km9Yd4E3U+CEUyDd0Bmc/YbPa\n" + - "htuXVsXJwiwlwooomujIIENhFw3htdcsu2apRj8EYUrKL8Mvvn+h16gDyobj0f01\n" + - "jWXlUgmH2lzUzca5eGuphfvmWN/ME/yqC2mMvWGnWySycqtT8VdJAgMBAAGjggFj\n" + - "MIIBXzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYEFFENOZBwFkjVdQX0iK32c77z\n" + - "SUl6MB8GA1UdIwQYMBaAFGLUQl6GcHVqkLzGuNJNYMI0ulE6MB0GA1UdJQQWMBQG\n" + - "CCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGG\n" + - "IWh0dHA6Ly9vY3NwLnNjYTFhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYq\n" + - "aHR0cDovL2NydC5zY2ExYS5hbWF6b250cnVzdC5jb20vc2NhMWEuY2VyMCUGA1Ud\n" + - "EQQeMByCGmdvb2Quc2NhMWEuYW1hem9udHJ1c3QuY29tMFAGA1UdIARJMEcwDQYL\n" + - "YIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcCARYfaHR0cHM6Ly93d3cu\n" + - "YW1hem9udHJ1c3QuY29tL2NwczANBgkqhkiG9w0BAQsFAAOCAQEAmn7z6Ub1sL77\n" + - "wyUEaCq/Odqm+2RtYYMJ1MeW6nTXTfAgZ/iLx/6hStafd9AK9gHiTCggBpj6KgnF\n" + - "UsGMDeX879jP675fH6SEk710QPDhIrfAzwE0pF/eUNsd7pLwne32zHX0ouCoAt4d\n" + - "KwBCZkKNUkdj4U+bpOJzvtcTP9JlzziLp9IFRjjQh3xKgfblx57CmRJbqH3fT5JJ\n" + - "IAIDVTz3ZUcqhPTFAnNsO1oNBEyrO5X9rwCiSy7aRijY/11R75mIIvyA9zyd9ss1\n" + - "kvrrER0GWMTDvC84FZD2vhkXgPTFrB1Dn9f3QgO5APT9GCFY5hdpqqPEXOSdRzQo\n" + - "h9j4OQAqtA==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.sca1a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 1A, O=Amazon, C=US - // Serial number: 6f1d774ad5e7b6d251d217661782bbdb6f37d - // Valid from: Mon Jan 28 15:34:38 PST 2019 until: Thu Apr 28 16:34:38 PDT 2022 + "MIIGKDCCBRCgAwIBAgIQBgxug3sudYbYRk6zT0qF/jANBgkqhkiG9w0BAQsFADA8\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + + "UlNBIDIwNDggTTAyMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLTEr\n" + + "MCkGA1UEAxMidmFsaWQucm9vdGNhMS5kZW1vLmFtYXpvbnRydXN0LmNvbTCCASIw\n" + + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3hA+omhUcO8nYO8/+dkpbYz8WI\n" + + "1ms7Y7JA2pPFfp2N/aWcf6m5ORm1BkyGLOttjTu318Qpa9eahQ1Pi3RNe3BtqjD9\n" + + "jcHncpwAFMsXy1beZA7sZ7AA4vKltA3t6yrU5ruTLUGQwUndeIBBSTW5QpdT9I/p\n" + + "EM7d+Miwre63kofbJ1lVPAJvN/udMVqGWNF8V5qscklUUHoSKA3FWWsiCyIgnthg\n" + + "G3u6R1KH66Qionp0ho/ttvrBCI0C/bdrdH+wybFv8oFFvAW2U9xn2Azt47/2kHHm\n" + + "tTRjrgufhDbcz/MLR6hwBXAJuwVvJZmSqe7B4IILFexu6wjxZfyqVm2FMr8CAwEA\n" + + "AaOCAzMwggMvMB8GA1UdIwQYMBaAFMAxUs1aUMOCfHRxzsvpnPl664LiMB0GA1Ud\n" + + "DgQWBBSkrnsTnjwYhDRAeLy/9FXm/7hApDBlBgNVHREEXjBcgiJ2YWxpZC5yb290\n" + + "Y2ExLmRlbW8uYW1hem9udHJ1c3QuY29tghpnb29kLnNjYTBhLmFtYXpvbnRydXN0\n" + + "LmNvbYIaZ29vZC5zY2ExYS5hbWF6b250cnVzdC5jb20wDgYDVR0PAQH/BAQDAgWg\n" + + "MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAs\n" + + "hipodHRwOi8vY3JsLnIybTAyLmFtYXpvbnRydXN0LmNvbS9yMm0wMi5jcmwwEwYD\n" + + "VR0gBAwwCjAIBgZngQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFo\n" + + "dHRwOi8vb2NzcC5yMm0wMi5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0\n" + + "dHA6Ly9jcnQucjJtMDIuYW1hem9udHJ1c3QuY29tL3IybTAyLmNlcjAMBgNVHRMB\n" + + "Af8EAjAAMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVct520\n" + + "zROiModGfLzs3sNRSFlGcR+1mwAAAYgHvXWVAAAEAwBHMEUCICAs74qT1f9ufSr5\n" + + "PgQqtQFiXBbmbb3i4xwVV78USU5NAiEA/iJEfnTG+hZZaHYv2wVbg6tUY8fQgIhI\n" + + "2rbl6PrD9FIAdgBIsONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYgH\n" + + "vXWWAAAEAwBHMEUCIQDf2nWyee/5+vSgk/O8P0BFvXYu89cyAugZHyd919BdAgIg\n" + + "UnGGpQtZmWnPMmdgpzI7jrCLuC370Tn0i7Aktdzj2X8AdgDatr9rP7W2Ip+bwrtc\n" + + "a+hwkXFsu1GEhTS9pD0wSNf7qwAAAYgHvXVpAAAEAwBHMEUCIGN6cT+6uwDospXe\n" + + "gMa8b38oXouXUT66X2gOiJ0SoRyQAiEAjDMu2vEll5tRpUvU8cD4gR2xV4hqoDxx\n" + + "Q+QGW+PvJxcwDQYJKoZIhvcNAQELBQADggEBACtxC3LlQvULeI3lt7ZYFSWndEhm\n" + + "tNUotoeKSXJXdoIpqSr10bzMPX9SHvemgOUtzP3JNqWPHw1uW9YFyeDE6yWj/B13\n" + + "Xj1hv1cqYIwyaOZBerU/9PT5PaCn20AC9DHbc7iBv+zs+DYiqlAFJ1GVaprwLul4\n" + + "8wp3gnC3Hjb8NykydCo6vw0AJ2UzjpjiTyVZ93jITzLOiboOUa1gQGnojzWlYaet\n" + + "sXe+RDylBp/Wuj1ZS7v/etltzYm5GanPi4y/p7Ta3Uky6std/GM6XbPRdBEFboFR\n" + + "B2IP0divd9c74Q+tLgpsAz5yXm9LtYPMcEPC2YRN2PgBg67c5+A7eIOluuw=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.rootca1.demo.amazontrust.com + // Issuer: CN=Amazon RSA 2048 M01, O=Amazon, C=US + // Serial number: e1023665b1268d788cc25bf69a9d05e + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIE2zCCA8OgAwIBAgITBvHXdK1ee20lHSF2YXgrvbbzfTANBgkqhkiG9w0BAQsF\n" + - "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + - "ZXIgQ0EgMUExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM0MzhaFw0yMjA0\n" + - "MjgyMzM0MzhaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + - "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" + - "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" + - "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" + - "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTFhLmFtYXpvbnRydXN0LmNvbTCCASIwDQYJ\n" + - "KoZIhvcNAQEBBQADggEPADCCAQoCggEBANUoHop9sW+QlgVsdtacioraTAWHcSTd\n" + - "MNkOkOEMgJIFPyfdcDvW/H2NvpdYeIQqzaCgT2kcsONWTZTPJMirCPnzl1ohHOZU\n" + - "uTnOVkamGxvNmQCURLBXmlCMRTCI5RY3CuYntFFbSPAnbumsF+K/gKqcE6ME53Bw\n" + - "PAwn4qwavB0i5Ib7Jk8XYzxSYXC9l8QLxt6fshPJRlecpXzfmVFvMAm3IbaLcpuv\n" + - "AtD+8I2KwjNtBPRPNYeFsWxwsgUGAyHEGa61oTGUqqAXu5YmPfyK+YTOJdoofsh4\n" + - "Tf3K7AKxnPWuvY3RNTs1pzEVwJYZqSsNwbgyKJJ4+0Xe4iP7qB8SYf8CAwEAAaOC\n" + - "ASkwggElMA4GA1UdDwEB/wQEAwIFoDAdBgNVHQ4EFgQUGHreoz+LP/Wr+RKzuexO\n" + - "V8ICtmEwHwYDVR0jBBgwFoAUYtRCXoZwdWqQvMa40k1gwjS6UTowHQYDVR0lBBYw\n" + - "FAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcw\n" + - "AYYhaHR0cDovL29jc3Auc2NhMWEuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAC\n" + - "hipodHRwOi8vY3J0LnNjYTFhLmFtYXpvbnRydXN0LmNvbS9zY2ExYS5jZXIwKAYD\n" + - "VR0RBCEwH4IdcmV2b2tlZC5zY2ExYS5hbWF6b250cnVzdC5jb20wEwYDVR0gBAww\n" + - "CjAIBgZngQwBAgEwDQYJKoZIhvcNAQELBQADggEBABSbe1UCLL7Qay6XK5wD8B5a\n" + - "wvR1XG3UrggpVIz/w5cutEm/yE71hzE0gag/3YPbNYEnaLbJH+9jz4YW9wd/cEPj\n" + - "xSK5PErAQjCd+aA4LKN1xqkSysgYknl0y47hJBXGnWf+hxvBBHeSoUzM0KIC21pC\n" + - "ZyXrmfaPCQAz13ruYIYdQaETqXGVORmKbf/a+Zn18/tfQt0LeeCYVoSopbXWQvcJ\n" + - "gUMtdIqYQmb8aVj0pdZXwKl4yZ2DtlS3Z9MpWNgQNlhRPmiYlu28y2yTtZ9SwD6m\n" + - "2f+cwc19aJrDT4Y280px+jRU7dIE6oZVJU+yBRVIZYpUFAB7extCMVxnTkCf8Dk=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // EE certificates don't have CRLDP extension - if (!ocspEnabled){ - pathValidator.validate(new String[]{INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); + "MIIGMjCCBRqgAwIBAgIQDhAjZlsSaNeIzCW/aanQXjANBgkqhkiG9w0BAQsFADA8\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + + "UlNBIDIwNDggTTAxMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLzEt\n" + + "MCsGA1UEAxMkcmV2b2tlZC5yb290Y2ExLmRlbW8uYW1hem9udHJ1c3QuY29tMIIB\n" + + "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxSPd1PWACxZohFCAJT1JWuXK\n" + + "GY29wZZ9yY0zoiq6+qYiUIU0crktytUNNI1ZpW/3qXpEw2ZQkM6WF1LshXtwGwrA\n" + + "zJwSeX1L9T5rOKhoBvoFeqfX7xu4VBM1/fDGt5X+NRFfD9Op9UfK5OsnL05TYach\n" + + "rdnfOA5wKGvMgFiN5CeOD0AtumXSuAnTZC85ojJTHjPF+hqV893WvrrUxLyyxtvh\n" + + "lq/WttFOjhfQu2IkfyDAFiH939uzUi0WSTAdsbsHuko5mDTDnOfMRbaaWZu0At01\n" + + "EgaIPeK+kGdi7EYwVndIwTKLeQ4mjIM8aj8Heg/y2hZ0kOmfCUZdUmJFlNoCIQID\n" + + "AQABo4IDOzCCAzcwHwYDVR0jBBgwFoAUgbgOY4qJEhjl+js7UJWf5uWQE4UwHQYD\n" + + "VR0OBBYEFMeBhIOkuWUY4DYqFrfgbD2eUeFtMG0GA1UdEQRmMGSCJHJldm9rZWQu\n" + + "cm9vdGNhMS5kZW1vLmFtYXpvbnRydXN0LmNvbYIdcmV2b2tlZC5zY2EwYS5hbWF6\n" + + "b250cnVzdC5jb22CHXJldm9rZWQuc2NhMWEuYW1hem9udHJ1c3QuY29tMA4GA1Ud\n" + + "DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0f\n" + + "BDQwMjAwoC6gLIYqaHR0cDovL2NybC5yMm0wMS5hbWF6b250cnVzdC5jb20vcjJt\n" + + "MDEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggr\n" + + "BgEFBQcwAYYhaHR0cDovL29jc3AucjJtMDEuYW1hem9udHJ1c3QuY29tMDYGCCsG\n" + + "AQUFBzAChipodHRwOi8vY3J0LnIybTAxLmFtYXpvbnRydXN0LmNvbS9yMm0wMS5j\n" + + "ZXIwDAYDVR0TAQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA7s3Q\n" + + "ZNXbGs7FXLedtM0TojKHRny87N7DUUhZRnEftZsAAAGIB72TggAABAMARzBFAiAZ\n" + + "naLbRHRuaRrE304GSuWX/79MU/e+SSlr0cNJ0kNNaAIhAPnz9HayL4txhkTEZiMs\n" + + "nttNnNqD17I0J17JLVOF4i/4AHYASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/\n" + + "qznYhHMAAAGIB72TmwAABAMARzBFAiEAgEqT7CYGQ/u36/3YcxBH78QfknI9kgcY\n" + + "sgJLkurUF6cCIFZZ/b803+ek6o+bmdV/uVx2UlskAyyolZ2okBAb6IscAHYA2ra/\n" + + "az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGIB72TbQAABAMARzBFAiEA\n" + + "6z2RSoK263hvYF71rj1d0TpC70/6zagSRR4glHOT6IACICYvaMAnrCNSTSiZ20Wz\n" + + "Ju5roTippO3BWKhQYrTKZuu4MA0GCSqGSIb3DQEBCwUAA4IBAQB4S1JGulFpMIaP\n" + + "NtLUJmjWz8eexQdWLDVF+H8dd6xpZgpiYtig/Ynphzuk1IIF8DkT3CeK/9vrezgI\n" + + "igNjneN9B4eIuzi/rJzIKeUwpZ2k5D+36Ab4esseoc+TopmNerw8hidt2g818jER\n" + + "D71ppSMakeQFPGe/Hs2/cVa/G1DNVcU2XAut45yRZ/+xsZ0/mcBDVsG9P5uGCN5O\n" + + "7SAp4J959WnKDqgVuU9WowPE5IjmS9BAv2gjniFYdDV2yksyf7+8edHd1KfSVX06\n" + + "pLx6CuCVZGJFG4Q2Aa1YAh1Wvt9hqWeXXpNRO2/wChL5rhT4GajsrGepsk4bjxYX\n" + + "Wf2iZ8mX\n" + + "-----END CERTIFICATE-----"; - return; - } + public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid - pathValidator.validate(new String[]{VALID, INT}, + pathValidator.validate(new String[]{VALID, INT_VALID}, ValidatePathWithParams.Status.GOOD, null, System.out); // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, + pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, ValidatePathWithParams.Status.REVOKED, - "Mon Jan 28 15:35:56 PST 2019", System.out); + "Mon May 15 13:36:57 PDT 2023", System.out); } } class AmazonCA_2 { - // Owner: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US + // Owner: CN=Amazon RSA 4096 M02, O=Amazon, C=US // Issuer: CN=Amazon Root CA 2, O=Amazon, C=US - // Serial number: 67f945755f187a91f8163f3e624620177ff38 - // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 + // Serial number: 773125b0c34c3c940299a9f04a39e5a52ccd9 + // Valid from: Tue Aug 23 15:29:13 PDT 2022 until: Fri Aug 23 15:29:13 PDT 2030 private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGRzCCBC+gAwIBAgITBn+UV1Xxh6kfgWPz5iRiAXf/ODANBgkqhkiG9w0BAQwF\n" + + "MIIGXjCCBEagAwIBAgITB3MSWww0w8lAKZqfBKOeWlLM2TANBgkqhkiG9w0BAQwF\n" + "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n" + - "b24gUm9vdCBDQSAyMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL\n" + - "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB\n" + - "IDJBMQ8wDQYDVQQDEwZBbWF6b24wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n" + - "AoICAQC0P8hSLewmrZ41CCPBQytZs5NBFMq5ztbnMf+kZUp9S25LPfjNW3zgC/6E\n" + - "qCTWNVMMHhq7ez9IQJk48qbfBTLlZkuKnUWbA9vowrDfcxUN0mRE4B/TJbveXyTf\n" + - "vE91iDlqDrERecE9D8sdjzURrtHTp27lZdRkXFvfEVCq4hl3sHkzjodisaQthLp1\n" + - "gLsiA7vKt+8zcL4Aeq52UyYb8r4/jdZ3KaQp8O/T4VwDCRKm8ey3kttpJWaflci7\n" + - "eRzNjY7gE3NMANVXCeQwOBfH2GjINFCObmPsqiBuoAnsv2k5aQLNoU1OZk08ClXm\n" + - "mEZ2rI5qZUTX1HuefBJnpMkPugFCw8afaHnB13SkLE7wxX8SZRdDIe5WiwyDL1tR\n" + - "2+8lpz4JsMoFopHmD3GaHyjbN+hkOqHgLltwewOsiyM0u3CZphypN2KeD+1FLjnY\n" + - "TgdIAd1FRgK2ZXDDrEdjnsSEfShKf0l4mFPSBs9E3U6sLmubDRXKLLLpa/dF4eKu\n" + - "LEKS1bXYT28iM6D5gSCnzho5G4d18jQD/slmc5XmRo5Pig0RyBwDaLuxeIZuiJ0A\n" + - "J6YFhffbrLYF5dEQl0cU+t3VBK5u/o1WkWXsZawU038lWn/AXerodT/pAcrtWA4E\n" + - "NQEN09WEKMhZVPhqdwhF/Gusr04mQtKt7T2v6UMQvtVglv5E7wIDAQABo4IBOTCC\n" + - "ATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYE\n" + - "FNpDStD8AcBLv1gnjHbNCoHzlC70MB8GA1UdIwQYMBaAFLAM8Eww9AVYAkj9M+VS\n" + - "r0uE42ZSMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3Au\n" + - "cm9vdGNhMi5hbWF6b250cnVzdC5jb20wOgYIKwYBBQUHMAKGLmh0dHA6Ly9jcnQu\n" + - "cm9vdGNhMi5hbWF6b250cnVzdC5jb20vcm9vdGNhMi5jZXIwPwYDVR0fBDgwNjA0\n" + - "oDKgMIYuaHR0cDovL2NybC5yb290Y2EyLmFtYXpvbnRydXN0LmNvbS9yb290Y2Ey\n" + - "LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggIBAEO5W+iF\n" + - "yChjDyyrmiwFupVWQ0Xy2ReFNQiZq7XKVHvsLQe01moSLnxcBxioOPBKt1KkZO7w\n" + - "Gcbmke0+7AxLaG/F5NPnzRtK1/pRhXQ0XdU8pVh/1/h4GoqRlZ/eN0JDarUhZPkV\n" + - "kSr96LUYDTxcsAidF7zkzWfmtcJg/Aw8mi14xKVEa6aVyKu54c8kKkdlt0WaigOv\n" + - "Z/xYhxp24AfoFKaIraDNdsD8q2N7eDYeN4WGLzNSlil+iFjzflI9mq1hTuI/ZNjV\n" + - "rbvob6FUQ8Cc524gMjbpZCNuZ1gfXzwwhGp0AnQF6CJsWF9uwPpZEVFnnnfiWH3M\n" + - "oup41EvBhqaAqOlny0sm5pI82nRUCAE3DLkJ1+eAtdQaYblZQkQrRyTuPmJEm+5y\n" + - "QwdDVw6uHc5OsSj/tyhh8zJ2Xq3zgh3dMONGjJEysxGaCoIb+61PWwMy2dIarVwI\n" + - "r+c+AY+3PrhgBspNdWZ87JzNHii7ksdjUSVGTTy1vGXgPYrv0lp0IMnKaZP58xiw\n" + - "rDx7uTlQuPVWNOZvCaT3ZcoxTsNKNscIUe+WJjWx5hdzpv/oksDPY5ltZ0j3hlDS\n" + - "D+Itk95/cNJVRM/0HpxI1SX9MTZtOSJoEDdUtOpVaOuBAvEK4gvTzdt0r5L+fuI6\n" + - "o5LAuRo/LO1xVRH49KFRoaznzU3Ch9+kbPb3\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US - // Serial number: 703e4e70616c90d611fd04a5ecc635665184e - // Valid from: Mon Jul 29 16:54:06 PDT 2019 until: Sat Aug 29 16:54:06 PDT 2020 + "b24gUm9vdCBDQSAyMB4XDTIyMDgyMzIyMjkxM1oXDTMwMDgyMzIyMjkxM1owPDEL\n" + + "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\n" + + "QSA0MDk2IE0wMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMGMl/pZ\n" + + "1OsxHY9gw/YfdON4mmrANkPwi7z2djHA5ELt/vRI3Su0le6OoipLf03iyoCnYy4Y\n" + + "rpfTbhyDriE8NJpps2ODJ5W1h0rz6FM1Q5Jt35wfk+4CEfATBTegHVlUJ0rJgzK5\n" + + "Yl/jrk12ZsC4ZeRn54shszcK6bHj4LZIHXhrYIIfetBMMD8V7hlhd54AclEWutUV\n" + + "eBEjkSCzDSk+pQKIjCL0crqvRSPvUNry/BV65zfGmceSYxpcLmV7k7Spwpo+1z8w\n" + + "+Odfnx2vsm7olPldfaThqk6fXBtInORl4Ef32xF3VDT13UeXtQPolFhnp8UOci64\n" + + "bW+R8tbtGpUXIA8Dhr8SgYPH6NW4jhUD4+AG8yer8ctA1Hl9tq+6tYr26q3yuCLu\n" + + "5rwJdfMG634fWIRXSj+GJi8SfAdGtPyXwu5799NWesV4vUkrkSXdIBK4TQCuK+jx\n" + + "aJ5Y+Zo2l3GFsWyMPNORLjoQXbjF6KAyjTyICLq9VzoQKhyx4Ll2CNrQv8CxqtDC\n" + + "GvXi9kREJYAF6lscOB0xglAAF5lndcaNkVHEVOMdg9ZZtdJywHWm8Qed1Wty2qr+\n" + + "hmA7booWQNRE12nW1niC5D4cP2ykPK9HSgb7xWdUF32VidUc9tNKM6xKjSd/R/tP\n" + + "p+XAybNSwEooPt3/OvyhpVRjLuWoqqbClTKdAgMBAAGjggFaMIIBVjASBgNVHRMB\n" + + "Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcD\n" + + "AQYIKwYBBQUHAwIwHQYDVR0OBBYEFJ5xHxodk6nZLY7MSFM/A1TznuZmMB8GA1Ud\n" + + "IwQYMBaAFLAM8Eww9AVYAkj9M+VSr0uE42ZSMHsGCCsGAQUFBwEBBG8wbTAvBggr\n" + + "BgEFBQcwAYYjaHR0cDovL29jc3Aucm9vdGNhMi5hbWF6b250cnVzdC5jb20wOgYI\n" + + "KwYBBQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhMi5hbWF6b250cnVzdC5jb20vcm9v\n" + + "dGNhMi5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2EyLmFt\n" + + "YXpvbnRydXN0LmNvbS9yb290Y2EyLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATAN\n" + + "BgkqhkiG9w0BAQwFAAOCAgEAl1GgKXOn0j1MWT1KJVSewQ28SGbie3UwZj1dMsjJ\n" + + "amCrQPn2ngSNbLm9+ulFiBDU8xKR9Zx3tZps55IUKWLUPkfMC+vkV7asDBqqzzE0\n" + + "F/MkekgPfOjx1V9S6Wfg3sSg+9KcluurXFElruqKfOm4cqmkV776X1G+AaaQ7mlU\n" + + "giCYi6NqRQSyhn8zrKkNnbO6QL5a9ICC47kiZYRAR/hRvZOt11QUK5tCMXJXo0iO\n" + + "4XKkMu+jdnehP1kh4xuZhYznIgKK6MJIITFI/Jj89U4SOPncyuS94sUuE2EqvvO/\n" + + "t81qeoey6wThz5iRbU/0CvDFnTMgebWGUZ2UZJ+az/rb3KYXGfVWasLIonkvYT7z\n" + + "vHOGNAA9oQ8TTgPOmPfSVyfpplKtO/aybWp5QSH2csIwuvw5dkmpkc42iD57XHob\n" + + "5LbMJg99z3vQBmod/ipmOpND95/BeA2mllBZgZ53S0nvDXDzbzR9Fd81PAz9Qruo\n" + + "dOJKcD6plKQjZjkLzNh1v/RoCFO8kiJGE4UBMTM8FUk0DXH4bALII4wwmDelrSUu\n" + + "lKvDTDxZvPF4dbEXICNPd51EMGPgETxwboOV+bzWFVI0IWQ8PhZ2VuMPDk2taOMp\n" + + "NsuLtlYc2twPb9r/Hvgv7G6+ItpBHZwOVt1oI3pHbjMp7P3pOZSPr6G1WkNy9mX8\n" + + "rVc=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=valid.rootca2.demo.amazontrust.com + // Issuer: CN=Amazon RSA 4096 M02, O=Amazon, C=US + // Serial number: 662f7646d76193cbb76946d111e49fa + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIHEzCCBPugAwIBAgITBwPk5wYWyQ1hH9BKXsxjVmUYTjANBgkqhkiG9w0BAQwF\n" + - "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + - "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0MDZaFw0yMDA4\n" + - "MjkyMzU0MDZaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + - "AQITCERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4G\n" + - "A1UEBRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x\n" + - "EDAOBgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNl\n" + - "czEjMCEGA1UEAxMaZ29vZC5zY2EyYS5hbWF6b250cnVzdC5jb20wggIiMA0GCSqG\n" + - "SIb3DQEBAQUAA4ICDwAwggIKAoICAQC+XjOB3ZCFX+b9y9reP+e6EAQz4ytiMSqU\n" + - "O4s5MyYLkY6n4BIZHmgWeQ2IgW1VrH8ho+Iu3UsTiuhd3/L/q/w+T0OJfcrWngTs\n" + - "uVcIuvUr32ObPeeWbg/m/lkN7hqH1jY62iybYVrFXiLo1+0G92PUazcyNvyA20+G\n" + - "HsvGG5jlArWNgRLdc8KUXxvnDUxx5vu4jeHEZnqSwuulV1h9ve0UutkmoK0Sk7Rz\n" + - "HMxYK0LmUT5OvcNQSkUi5nLi+M1FxnYYgsELwSiKSSEDfEdgxooMAiVTgw51Q/DB\n" + - "lTOjAIDL3K3J0yGfIG3bwLvE1qz2Z5yWn8f3JibIah7LrC4PiZDDLHFM6V9l+YqU\n" + - "RqimJ5BltSyAx7bxQNZ1AW3Lxvvm894i4k6/Vdf1CDovRuTMPCDAQmKA/A/AQ7TN\n" + - "q3bBimX6UyuJu0I8RyvAYKzFhOOqe4vXrbndTbje/jnzTNQPeIIcuRa9cgXTOrbw\n" + - "86FTUKj6AZXihRWjKWsQpDwdgE0tQETZ3ynCXfbBKfFmn0MSjeX0CEEAZdYHR8EV\n" + - "F271Yt7UJjS/FP702aHTOWk7zFbIRfFQODvBhn0I8p/Stk2sDq4/YsbXVZOe3+ad\n" + - "YavoiODGSAH6ZcZzULumgK9eii0koAOPB/xqXnkcTS63gEHOKjLQl3hqdVZRCugv\n" + - "1CwUXLvoSwIDAQABo4IBYzCCAV8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdDgQWBBTa\n" + - "j6dHgPdOxTGLcwaNDeaMnlSxNjAfBgNVHSMEGDAWgBTaQ0rQ/AHAS79YJ4x2zQqB\n" + - "85Qu9DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdQYIKwYBBQUHAQEE\n" + - "aTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5zY2EyYS5hbWF6b250cnVzdC5j\n" + - "b20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2NhMmEuYW1hem9udHJ1c3QuY29t\n" + - "L3NjYTJhLmNlcjAlBgNVHREEHjAcghpnb29kLnNjYTJhLmFtYXpvbnRydXN0LmNv\n" + - "bTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYGBWeBDAEBMC0wKwYIKwYBBQUH\n" + - "AgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNvbS9jcHMwDQYJKoZIhvcNAQEM\n" + - "BQADggIBAE6RwZAZvN0i9ygwzqoX9DhSPtvZ3xIO0G0Bhgjkb986+p8XJstU3gEM\n" + - "8P2i1J/YthXCnRGedm+Odxx+31G6xIYfP5S5g7HyRGkj/aXNXy4s3KjH8HJgOY9N\n" + - "ra3XfC05OKq5FpyZQDZ+hxCdLrH3Gs+UxREbu+LuIKUpI7nMVEjn9XynKyOdKN21\n" + - "Kq5VsuI0fDWCYvUN1M+lI/LgE5HbNJVQJs+dB7g1/kaOeaLia7Wk1ys+uRzB58rp\n" + - "FKAoLk++HWTfNDkbN8vKRfHhJ/xhI9ju3TWcci6EyFVAym1C62UkJNI0KHgQ+zc7\n" + - "nl1tv/ytj8N/eJoysyp23lJ5qrVetlQORfgXryGkWBMYBvYF8zbBb/f+UXHDKVWt\n" + - "9l1lL6HQGY/tTo253pj6/FgDD35bZdjLQeUVmbnz679S5oUmoH5ZtSdnpUTghU3p\n" + - "bae9adBFY9S1pm50Q3ckRVBAwNqNmI0KKUh14Ms8KSAUHg19NvGsBonqwOT2rdbv\n" + - "xZ47N6c2eCl/cjMvzre0v0NoUO+3og2GHeAoOwVos6480YDbMqp739tOFPxBcsII\n" + - "6SjpDVh+14dkSW6kEKeaCFLR+eChqutri1VQbQ49nmADQWw9Al8vBytSnPv0YN6W\n" + - "XfIE1Qj7YmHu/UuoeKVsqDqoP/no29+96dtfd4afJqlIoyZUqXpt\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.sca2a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - //Issuer: CN=Amazon, OU=Server CA 2A, O=Amazon, C=US - //Serial number: 6f1d782c0aa2f4866b7b522c279b939b92369 - //Valid from: Mon Jan 28 15:37:45 PST 2019 until: Thu Apr 28 16:37:45 PDT 2022 + "MIIICzCCBfOgAwIBAgIQBmL3ZG12GTy7dpRtER5J+jANBgkqhkiG9w0BAQwFADA8\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + + "UlNBIDQwOTYgTTAyMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLTEr\n" + + "MCkGA1UEAxMidmFsaWQucm9vdGNhMi5kZW1vLmFtYXpvbnRydXN0LmNvbTCCAiIw\n" + + "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAON5EbEKoBiujI7Ja8mLZLJbaY7f\n" + + "RtoWIjU/F0l9ueWFogXmEaA1jWsl97F3WTHTyGKz6ChCjPMSyoXXpY+yoE90QUyX\n" + + "w35uWEhNrc40drMJkyN+QXitSrH346GCOKvpYVvu18UD4W8hDhg8vvbOQYhtmSf7\n" + + "Rfrs7/qUdXpzpvR9VjWktbQAzJT8fB/jFNjNQJTknynjGiYO5GF51+peOCLK6qw8\n" + + "9kKYEigR4K8/aWL283rC4xRxZqVioy433VG02l/Fwdv8o/vL9YYIqkyspCB9fpFw\n" + + "Q50yYrwEomxuOz7rXhmdfeNaFYuyTtOUSKff6p2oqO0S7pcLujUVMlO4dYBDELQF\n" + + "cabByNjwblviCtGKJMIzD6Thkgamp3iXQgcU498+P5r7N5CYbMmkJEdcuILg+bgJ\n" + + "/LUUTT+IMt2txYlO/ld3N0EHlgVt7rztW5mtm6Ba8jN7cLSh7ZWu6Fr1+oK7bl5T\n" + + "wPxSfqT5W3BwQKS3YptIoKEWUb+VNnS/dYx/7IspF9+z6kw4g+V2EY9M4ZYNakzM\n" + + "AI7KIj4thMFoWeYrJq0dUMZ297QCBPRdAwh9hhkq2LYi2x8tMUtcBnhb/q75sO+E\n" + + "icPqFVv7iMDZ/8Xep+0UoClF3JGmZW3UNtwcbi7Pn/OqtaMi7E8xnHUgc4ZchtXO\n" + + "v8VtVvDeZAlY5TjVAgMBAAGjggMWMIIDEjAfBgNVHSMEGDAWgBSecR8aHZOp2S2O\n" + + "zEhTPwNU857mZjAdBgNVHQ4EFgQUnGekBRKIZBYgCEajbpCMC24bp2owSQYDVR0R\n" + + "BEIwQIIidmFsaWQucm9vdGNhMi5kZW1vLmFtYXpvbnRydXN0LmNvbYIaZ29vZC5z\n" + + "Y2EyYS5hbWF6b250cnVzdC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG\n" + + "CCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3Js\n" + + "LnI0bTAyLmFtYXpvbnRydXN0LmNvbS9yNG0wMi5jcmwwEwYDVR0gBAwwCjAIBgZn\n" + + "gQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5y\n" + + "NG0wMi5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQucjRt\n" + + "MDIuYW1hem9udHJ1c3QuY29tL3I0bTAyLmNlcjAMBgNVHRMBAf8EAjAAMIIBfQYK\n" + + "KwYBBAHWeQIEAgSCAW0EggFpAWcAdgDuzdBk1dsazsVct520zROiModGfLzs3sNR\n" + + "SFlGcR+1mwAAAYgHvX9QAAAEAwBHMEUCIQD8qPPCLL2Grd+/YNALWqAq7LC7YBaa\n" + + "dNg5+6Q4kRDEqgIgEkf/UMsMNfTRaOZvoOgAK9/F0xX/CfdcUTjULhmoA+cAdQBI\n" + + "sONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYgHvX8UAAAEAwBGMEQC\n" + + "IBVFDtapMMWJOqyu8Cv6XEhFmbU8N33c2owed//pa80xAiAT9T6Wba3B9DFUmrL5\n" + + "cCGKLqciIEUPhPbvjCuUepelrAB2ANq2v2s/tbYin5vCu1xr6HCRcWy7UYSFNL2k\n" + + "PTBI1/urAAABiAe9ft8AAAQDAEcwRQIhAP2XDC/RlmVtH4WrfSwVosR/f/WXRhG5\n" + + "mk9Nwq+ZOIriAiAopPXSH7VwXa3bEAIiTwcV1l10QIDZaIPCU5olknU5CjANBgkq\n" + + "hkiG9w0BAQwFAAOCAgEAFuwMIJdP5rgz6cqOIj2EgF2OU8CUGi/wJ45BomXWv4Rv\n" + + "U5mOKB+jHOGZZC9dncjAMa44RwoF2I7/8Y3qLVaoNm46ObvvS+6UvzTcyQqXM7JU\n" + + "cSmdlf9DkspjKPDvMBokVrM4ak5AoxUjuru5qaia3nvbxq7XKO9/FGUaUaU8Xlsd\n" + + "V6Fo8VmNwFc88VCqOp8eI/IicHxMDLl8TKXMvr3CYh8A9nCeFGcV+4CL+7JF2t5K\n" + + "YvV5r074Wyk0QMlRVYMNDl0t+VAEoDJ7RRE+kEvplWcsX9S2wvr4HhkA4iChpwFm\n" + + "2UDTppHskSWyLsuNQvipn0zTzZ8RIxXd/ei0qCdhKmkV7x9cgbTiyXgaI7iJEtdo\n" + + "RvYNcXc2RmitWjY5Av8yJGOk0eYpCwRrBv6ughbtJe3NMrqUeTyrKidIEo9KnRSA\n" + + "rMokRbHunkroS97VkoK/9j9pNJki+qAH9XTLYWcm/5+cTSGRsN+escRgZwV6KWg/\n" + + "JQQe5LbwU2HHzNqWuk63GC/ngVlWXjaVFfbNVmYEKZFFazcZchesN1YyDu+WndOx\n" + + "+rTcuke2feOvQ4EnVviM0k85JZNiqPDH2iafAWyqZFUYTnb7XK3HhJflAniv/SLq\n" + + "DQfbJmtQtNHdJYgVmC1u2RT9gbJDIAj0ZI4vU2WVB5Hmd9F31un6jundEuG4+S4=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.rootca2.demo.amazontrust.com + // Issuer: CN=Amazon RSA 4096 M02, O=Amazon, C=US + // Serial number: 788baa8f47bc5b1c624424216240fd3 + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIG2zCCBMOgAwIBAgITBvHXgsCqL0hmt7Uiwnm5ObkjaTANBgkqhkiG9w0BAQwF\n" + - "ADBGMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2\n" + - "ZXIgQ0EgMkExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzM3NDVaFw0yMjA0\n" + - "MjgyMzM3NDVaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwC\n" + - "AQITCERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYD\n" + - "VQQFEwc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ\n" + - "MA4GA1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2Vz\n" + - "MSYwJAYDVQQDEx1yZXZva2VkLnNjYTJhLmFtYXpvbnRydXN0LmNvbTCCAiIwDQYJ\n" + - "KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKFm418X8hN1YTgD2XpMb4sp78mw8k3j\n" + - "Dq/vnpX48evVUzNpHpy4qRz/ZHBR4HUJO4lhfnX+CO0uRqqqx4F0JZRQB3KevaU8\n" + - "QGWHdJGhEddnurDhrgOUa+ZroqUnMCsTJfbyGtC6aiEXeu/eMhEUFkuBxJH1JtwD\n" + - "dQXMXuMjG07SVjOkhTkbMDzA/YbUqkDeOIybifDuvA5LEsl+kReY0b6RYFo2Tt/M\n" + - "dPhJD8q3Wsu+XCiCnbpcwlEVGxiD2RVRXJJ9o3ALGOxqU69V+lYS0kkwNHT7oV9J\n" + - "rhgt7iOCq0aoTAxu2j4FCp0JHNhGoW9pXoMXnmS6kK80hzLNYDxvKEaVaKkiYHw5\n" + - "CV0Vwii05ICa14nrStH/jcRNLyU+gp+6OeerPV3jpKWshGKWewF+2UiWU2WHTSrd\n" + - "Wis0/qEfFK/kSraAxpd+KavEEavKeudoMAHIxMACOk9E/fF5zhd2y4G1q1BdoRlR\n" + - "KP4GIV2v6qH6Ru2mNSuge9il6kDXxFNucrYKLDbAqkqalohkvDavcPoG9gZT3etv\n" + - "4IcgJriIWRxbJwKPpwJM+6wa6RpwoeJMuEp3ZBP7KDaQ8YX4rlf4zXLAsOKCNA9K\n" + - "OS/qYQ/I4g0E1WhfgEKClaLPS2u7jeVR6s1t4txGo4vq5Dkt17KTCew/WsX3rckf\n" + - "a2p5zvFcfpCNAgMBAAGjggEpMIIBJTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0OBBYE\n" + - "FAF8N1wV8EoYFkMXH6tEnmR/7vI+MB8GA1UdIwQYMBaAFNpDStD8AcBLv1gnjHbN\n" + - "CoHzlC70MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcB\n" + - "AQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTJhLmFtYXpvbnRydXN0\n" + - "LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2EyYS5hbWF6b250cnVzdC5j\n" + - "b20vc2NhMmEuY2VyMCgGA1UdEQQhMB+CHXJldm9rZWQuc2NhMmEuYW1hem9udHJ1\n" + - "c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBDAUAA4ICAQBC\n" + - "VwR1NFk1IYIF4cjU7ML1aj8OIn+8mtakGQnuSJLK6ypSysINJBS48ZDdP6XZXvyD\n" + - "iTS0xEAPjAZHTqrABdNYmvJeL2RnN99DIwVzBpZp4NLTXbiSW7jb0Y5cEPDGJMOo\n" + - "SUAAM6fsiPRfz5vX4XVPznbcF2AwE/NVV+L3n9LVRt7qv2VqIEvLioR56Dq+5ofR\n" + - "4bw0BVlEYWF4Gsy7WDDTL1iLNBUwZTqBHwTv0fgDRiPqb/odmLQuRANwcJy8B8Zr\n" + - "s/yX4SeESaRdA82lAlQilksQitXS2qvQN06GEDOgUxYE6EabFdgklV5JypKqdOly\n" + - "vzpaDpF3z5W8Bj3D4fns1Kjrh1pPh5JRvg+616diKnQRt4X5q+EtmnXhDvIGMISI\n" + - "FuGwj57CNQ2x2MY2HHKWPrOccpQfEEvoSNR+ntYWrtSSttZq948O+zZBk1TXWuXV\n" + - "TVXllqTg8lp6d5cfKgvtHKgt98WkpPOcLVrNuVnMAIfDw6ar54dVKqrvkeEcF6mJ\n" + - "7oMKjJX/Vu9lYoGViBIfdeqcCPWSI8BpnCKaG7dTQO3Q1ObGmLdGBRlsRh+d+S5l\n" + - "Fq326ckbjx537e5/ai31lOR7OwVh9TDweKLqIACjs987C0EJSEfoOue25WRww2va\n" + - "iX9SrTPm4GxQ2OJgYwx0+HbezJXFN+dhaOFUavTSFw==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // EE certificates don't have CRLDP extension - if (!ocspEnabled){ - pathValidator.validate(new String[]{INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); + "MIIIEjCCBfqgAwIBAgIQB4i6qPR7xbHGJEJCFiQP0zANBgkqhkiG9w0BAQwFADA8\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\n" + + "UlNBIDQwOTYgTTAyMB4XDTIzMDUxMDAwMDAwMFoXDTI0MDYwNzIzNTk1OVowLzEt\n" + + "MCsGA1UEAxMkcmV2b2tlZC5yb290Y2EyLmRlbW8uYW1hem9udHJ1c3QuY29tMIIC\n" + + "IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzJfddWdrWhA9dSJdmy23veN9\n" + + "oLvSqpM4YaXGZmPtKUmbFMLs2I3vCKrzflRKeOpl3MCc2hh6TH/3z+Q/fGugXLsY\n" + + "H8QcjSbiIOd15n+3dUFTLKaoWMyseMcWiOIVaN5rCDVXiAHdt1pc147wyFQIzqNK\n" + + "J/xiV1u9eT2MFue+4bd7kUNAcmI8M+SXruhto4jtAV8ugpTEChTDlyO/l8xmaM1Q\n" + + "HkijsHX7Aq72Q/3PH/U+wbJ9pmpTp4x2AEJoo45IGfB/NKDTrv5otLBuiP8Y0M7b\n" + + "K7irRPDFBqMNZw7S7p39SnC+V/WibJQk5Bo/8vcwDJX+WnDkw1QD/uXu3ugDzSDD\n" + + "iBDViMOdN+3K47s4x2kdssoh4WWScMlAVb4vyN7IA3J4TnwA/1uCWhw4LE1WvY7N\n" + + "etekhVP1eWF8IzNY0oo2u2ie79777xvBtmtp7RnvYLGv7I+xVhjH5qGNzn9fRCUm\n" + + "QDego5HAfJ0PLlMEagdW8asCak1WaC117adnibL6WPtFA2FD2i6gNalTvhXhK2Ex\n" + + "alGxrVd/BCseT3bMp783jqScJO1g6xRHu0Qx+RyrOGVvcKZa6Y0DcAc8psRpkHaO\n" + + "HZY+lE8O2CIxpAJlwSnD6BoDNo8sg1IqFNkECw3wqfeMPBcg38k6zjAxwRDcIx6U\n" + + "SwDl4d3sjrmy3gOFFXMCAwEAAaOCAxswggMXMB8GA1UdIwQYMBaAFJ5xHxodk6nZ\n" + + "LY7MSFM/A1TznuZmMB0GA1UdDgQWBBQXpWT7gMHO+HKoHM1gU1VQVnylRzBOBgNV\n" + + "HREERzBFgiRyZXZva2VkLnJvb3RjYTIuZGVtby5hbWF6b250cnVzdC5jb22CHXJl\n" + + "dm9rZWQuc2NhMmEuYW1hem9udHJ1c3QuY29tMA4GA1UdDwEB/wQEAwIFoDAdBgNV\n" + + "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0\n" + + "cDovL2NybC5yNG0wMi5hbWF6b250cnVzdC5jb20vcjRtMDIuY3JsMBMGA1UdIAQM\n" + + "MAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDov\n" + + "L29jc3AucjRtMDIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8v\n" + + "Y3J0LnI0bTAyLmFtYXpvbnRydXN0LmNvbS9yNG0wMi5jZXIwDAYDVR0TAQH/BAIw\n" + + "ADCCAX0GCisGAQQB1nkCBAIEggFtBIIBaQFnAHYA7s3QZNXbGs7FXLedtM0TojKH\n" + + "Rny87N7DUUhZRnEftZsAAAGIB72CzgAABAMARzBFAiEA2vPYIPfGJeynPaZHq/c0\n" + + "GGvyT6MpvFGMW0s0woLRT28CIEFbZbFSCnKugaqw9QDNi7vYmIF3Gyi3s6G2cCxY\n" + + "4RJXAHYASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGIB72DDgAA\n" + + "BAMARzBFAiAvfNcgtFEwk5C9dvMUYANbIAv0IOdF1new8Umn3cM+JwIhALbs/3L9\n" + + "0ndF7sRKDZmfronNruptFlrI528P5Qi2P528AHUA2ra/az+1tiKfm8K7XGvocJFx\n" + + "bLtRhIU0vaQ9MEjX+6sAAAGIB72CxQAABAMARjBEAiBKUns2FPbs0cThb6e7SnyL\n" + + "y4/qP3V1Q/ASt/ZDRTeEQQIgWSQO4Gsz32srtqYuTM9AsFd92WA44kJHincdcGVX\n" + + "XbIwDQYJKoZIhvcNAQEMBQADggIBAAnaNbn2wXylTCS7dtgB3rWdUf6hja1UDuvB\n" + + "uZEL2dUOvyXfVFLNxKdeWBPzqpwEBNNwPQXhoI97TXlyu2x60jLzQamoGoRQ3s0P\n" + + "NLhasLGEIQH/oYdMV/yp8EI8fUuRVE3xyw39FRqOrmsUFAnxNQmBO/09JM7sLcvS\n" + + "wwh14p9dFTTolJHgnL4ZEtmZxSddFG+GBSTJ/A7dVSmwIudwzd+goA6173BI6yeT\n" + + "hhQumLctQiOM7y1MzFeV8rL+oIpd2xuzyhKKT1EgvU6/wyt0Ib8QqsFsrXPnUOKk\n" + + "HAq3SeZyq35QUaTKoaH9L1iZMbSCG9Jm6FMb12SdAz53653tYvAiUS76oD8Jot13\n" + + "RZu5NUlWAVLLq0OaEtuGp0bh+cVtzVnCC9m1qa46YpY0SojpvSbakgQMMGIgDlT3\n" + + "wFE7tST4WlsDC1f/m+H9V5qz/j0U8D3eNNdowxPqx/JZq/sk9ZK5KyMFARrvM+fh\n" + + "YrVYjKt91mu7JaS4pPOyZmJ8OQ14EvrN7BXc7IkNrI1reeaRFe49k5DAETB8VmP5\n" + + "2F0SWou2KkgtJvU4Z7YjlZ2HNHnpjTK5KdPNpRSt7EUy2zn9NCNoyQhnws70FyXv\n" + + "oPFyG92lnUQOKaAUhVRwTr9fvnkdMOzSKg/spxi2Ogdzym5Jw68eguwi0dVqX2+9\n" + + "3zViP2aH\n" + + "-----END CERTIFICATE-----"; - return; - } + public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid pathValidator.validate(new String[]{VALID, INT}, @@ -344,201 +378,228 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Mon Jan 28 15:38:57 PST 2019", System.out); + "Mon May 15 13:38:54 PDT 2023", System.out); } } class AmazonCA_3 { - // Owner: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US + // Owner: CN=Amazon ECDSA 256 M02, O=Amazon, C=US // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US - // Serial number: 67f945758fe55b9ee3f75831d47f07d226c8a - // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIICuzCCAmGgAwIBAgITBn+UV1j+VbnuP3WDHUfwfSJsijAKBggqhkjOPQQDAjA5\n" + + // Serial number: 773126de2c2fafd2c47ad88b1566e0182046d + // Valid from: Tue Aug 23 15:33:24 PDT 2022 until: Fri Aug 23 15:33:24 PDT 2030 + private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIC1DCCAnmgAwIBAgITB3MSbeLC+v0sR62IsVZuAYIEbTAKBggqhkjOPQQDAjA5\n" + + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + + "Um9vdCBDQSAzMB4XDTIyMDgyMzIyMzMyNFoXDTMwMDgyMzIyMzMyNFowPTELMAkG\n" + + "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEdMBsGA1UEAxMUQW1hem9uIEVDRFNB\n" + + "IDI1NiBNMDIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS9vQLD4W/Kg4AnFRl8\n" + + "x/FUbLqtd5ICYjUijGsytF9hmgb/Dyk+Ebt4cw6rAlGbaiOLapSJKZiZr+UQdh3I\n" + + "QOr+o4IBWjCCAVYwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYw\n" + + "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBS7eJrXaDMy\n" + + "nRq7bP2xNEwB3svQdTAfBgNVHSMEGDAWgBSrttvXBp43rDCGB5Fwx5zEGbF4wDB7\n" + + "BggrBgEFBQcBAQRvMG0wLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLnJvb3RjYTMu\n" + + "YW1hem9udHJ1c3QuY29tMDoGCCsGAQUFBzAChi5odHRwOi8vY3J0LnJvb3RjYTMu\n" + + "YW1hem9udHJ1c3QuY29tL3Jvb3RjYTMuY2VyMD8GA1UdHwQ4MDYwNKAyoDCGLmh0\n" + + "dHA6Ly9jcmwucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNhMy5jcmwwEwYD\n" + + "VR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwIDSQAwRgIhAKSYEcDcp3kcPMzh\n" + + "OIYDWZOLu4InPod4fQhRTmc2zBAgAiEAmwdGE4AuNWhw9N8REhf82rJLNm7h9Myg\n" + + "TsR9Wu0bQYU=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Amazon ECDSA 256 M01, O=Amazon, C=US + // Issuer: CN=Amazon Root CA 3, O=Amazon, C=US + // Serial number: 773126684d577c0fcf8d3a342bea86f94fc8f + // Valid from: Tue Aug 23 15:31:46 PDT 2022 until: Fri Aug 23 15:31:46 PDT 2030 + private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIC0zCCAnmgAwIBAgITB3MSZoTVd8D8+NOjQr6ob5T8jzAKBggqhkjOPQQDAjA5\n" + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + - "Um9vdCBDQSAzMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" + - "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDNB\n" + - "MQ8wDQYDVQQDEwZBbWF6b24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATYcYsK\n" + - "mYdR0Gj8Xz45E/lfcTTnXhg2EtAIYBIHyXv/ZQyyyCas1aptX/I5T1coT6XK181g\n" + - "nB8hADuKfWlNoIYRo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8B\n" + - "Af8EBAMCAYYwHQYDVR0OBBYEFATc4JXl6LlrlKHvjFsxHhN+VZfaMB8GA1UdIwQY\n" + - "MBaAFKu229cGnjesMIYHkXDHnMQZsXjAMHsGCCsGAQUFBwEBBG8wbTAvBggrBgEF\n" + - "BQcwAYYjaHR0cDovL29jc3Aucm9vdGNhMy5hbWF6b250cnVzdC5jb20wOgYIKwYB\n" + - "BQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNh\n" + - "My5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2EzLmFtYXpv\n" + - "bnRydXN0LmNvbS9yb290Y2EzLmNybDARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZI\n" + - "zj0EAwIDSAAwRQIgOl/vux0qfxNm05W3eofa9lKwz6oKvdu6g6Sc0UlwgRcCIQCS\n" + - "WSQ6F6JHLoeOWLyFFF658eNKEKbkEGMHz34gLX/N3g==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US - // Serial number: 703e4e9bbc2605f37967a0e95f31f4789a677 - // Valid from: Mon Jul 29 16:54:43 PDT 2019 until: Sat Aug 29 16:54:43 PDT 2020 + "Um9vdCBDQSAzMB4XDTIyMDgyMzIyMzE0NloXDTMwMDgyMzIyMzE0NlowPTELMAkG\n" + + "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEdMBsGA1UEAxMUQW1hem9uIEVDRFNB\n" + + "IDI1NiBNMDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT80w+2RwNHzyXmVUM/\n" + + "OUKBZpJkTzHyCKDl4sBrUfjzVjot/lNba9kYzMKSHYv95CUDoMaF2h2KAqx65uLQ\n" + + "Y8ago4IBWjCCAVYwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYw\n" + + "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBRPWfy8BhYo\n" + + "v6LI2wj7zxMkumlCXDAfBgNVHSMEGDAWgBSrttvXBp43rDCGB5Fwx5zEGbF4wDB7\n" + + "BggrBgEFBQcBAQRvMG0wLwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLnJvb3RjYTMu\n" + + "YW1hem9udHJ1c3QuY29tMDoGCCsGAQUFBzAChi5odHRwOi8vY3J0LnJvb3RjYTMu\n" + + "YW1hem9udHJ1c3QuY29tL3Jvb3RjYTMuY2VyMD8GA1UdHwQ4MDYwNKAyoDCGLmh0\n" + + "dHA6Ly9jcmwucm9vdGNhMy5hbWF6b250cnVzdC5jb20vcm9vdGNhMy5jcmwwEwYD\n" + + "VR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwIDSAAwRQIhALRfxq3SQIhj5xA4\n" + + "S5UAY/KlKqayZDpnbBdCDH8Kqmf/AiAUVZddALefnqRe+ifxN2FUp461LL6/cgVM\n" + + "EH3Ty27f1Q==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=valid.rootca3.demo.amazontrust.com + // Issuer: CN=Amazon ECDSA 256 M02, O=Amazon, C=US + // Serial number: 8e2f14864fb28e4a1da0f15a5118cc8 + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIDhzCCAy2gAwIBAgITBwPk6bvCYF83lnoOlfMfR4mmdzAKBggqhkjOPQQDAjBG\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + - "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU0NDNaFw0yMDA4Mjky\n" + - "MzU0NDNaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + - "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" + - "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" + - "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" + - "MCEGA1UEAxMaZ29vZC5zY2EzYS5hbWF6b250cnVzdC5jb20wWTATBgcqhkjOPQIB\n" + - "BggqhkjOPQMBBwNCAARl4yxf8XcvWR0LZ+YuBC0CpkwtU2NiMdlIM7eX0lxhQp53\n" + - "NpLlCrPRNzOWrjCJDdn21D0u7PrtN94UHLHOg9X0o4IBYzCCAV8wDgYDVR0PAQH/\n" + - "BAQDAgeAMB0GA1UdDgQWBBT2cHmOJFLWfg1Op7xAdAnqYcwaPzAfBgNVHSMEGDAW\n" + - "gBQE3OCV5ei5a5Sh74xbMR4TflWX2jAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" + - "BQUHAwIwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5z\n" + - "Y2EzYS5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuc2Nh\n" + - "M2EuYW1hem9udHJ1c3QuY29tL3NjYTNhLmNlcjAlBgNVHREEHjAcghpnb29kLnNj\n" + - "YTNhLmFtYXpvbnRydXN0LmNvbTBQBgNVHSAESTBHMA0GC2CGSAGG/W4BBxgDMDYG\n" + - "BWeBDAEBMC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LmFtYXpvbnRydXN0LmNv\n" + - "bS9jcHMwCgYIKoZIzj0EAwIDSAAwRQIgURdcqJVr4PWNIkmWcSKmzgZ1i94hQpGe\n" + - "mWbE9osk4m0CIQDhxIguihwvDa5RsBwdM0aRDgGKLNHigGqJoKqgH0d2qg==\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.sca3a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 3A, O=Amazon, C=US - // Serial number: 6f1d78cf0ca64ce7f551a6f2a0715cc0e8b50 - // Valid from: Mon Jan 28 15:40:01 PST 2019 until: Thu Apr 28 16:40:01 PDT 2022 + "MIIEfjCCBCWgAwIBAgIQCOLxSGT7KOSh2g8VpRGMyDAKBggqhkjOPQQDAjA9MQsw\n" + + "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + + "U0EgMjU2IE0wMjAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC0xKzAp\n" + + "BgNVBAMTInZhbGlkLnJvb3RjYTMuZGVtby5hbWF6b250cnVzdC5jb20wWTATBgcq\n" + + "hkjOPQIBBggqhkjOPQMBBwNCAAQfWc7gBGBBBmseCb2XWWRQVhCUQDVml3mVgvj5\n" + + "RmnP1y5wpifUTFqu8ELdI7YGZ4JMSnetiKNmLtg5yhTEjzCQo4IDFTCCAxEwHwYD\n" + + "VR0jBBgwFoAUu3ia12gzMp0au2z9sTRMAd7L0HUwHQYDVR0OBBYEFHCE8orvZDUK\n" + + "5TI9MYadzxWR9CZGMEkGA1UdEQRCMECCInZhbGlkLnJvb3RjYTMuZGVtby5hbWF6\n" + + "b250cnVzdC5jb22CGmdvb2Quc2NhM2EuYW1hem9udHJ1c3QuY29tMA4GA1UdDwEB\n" + + "/wQEAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQw\n" + + "MjAwoC6gLIYqaHR0cDovL2NybC5lMm0wMi5hbWF6b250cnVzdC5jb20vZTJtMDIu\n" + + "Y3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEF\n" + + "BQcwAYYhaHR0cDovL29jc3AuZTJtMDIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUF\n" + + "BzAChipodHRwOi8vY3J0LmUybTAyLmFtYXpvbnRydXN0LmNvbS9lMm0wMi5jZXIw\n" + + "DAYDVR0TAQH/BAIwADCCAXwGCisGAQQB1nkCBAIEggFsBIIBaAFmAHUA7s3QZNXb\n" + + "Gs7FXLedtM0TojKHRny87N7DUUhZRnEftZsAAAGIB71y/gAABAMARjBEAiAEAXIb\n" + + "aOVR26HgFaI+qoIasCb8w2sOqVxGAxf5iPgX6QIgdAlMjqeoihi1arnJpzN8Bqxy\n" + + "5ULMUO7GK3JEgcogJHMAdgBIsONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiE\n" + + "cwAAAYgHvXLkAAAEAwBHMEUCIF7wDDmWxTHwBZM7Me8eOCM1aQ/g1c1rJg/I+NJa\n" + + "HkZYAiEA8p+IviuY5piHBELjUtVlZLiS9XSSMxpQNhUerqC/YFoAdQDatr9rP7W2\n" + + "Ip+bwrtca+hwkXFsu1GEhTS9pD0wSNf7qwAAAYgHvXKvAAAEAwBGMEQCIFLskZDs\n" + + "UG4+/88D/5/QbD9zT6ZmZlwXiPZ6H2YR/KiJAiBvi4vvNsb9KNAhJMgI2T2iCg9U\n" + + "CIru+US6y3ua7dKKDTAKBggqhkjOPQQDAgNHADBEAiAzvgzKV/kvBbKWCT1NNUBD\n" + + "AF9okIEcJx/ukFgzmYMwUQIgXeJeVf3izkxsgiEUSknwHsErLFs/cEme2PSRj2AW\n" + + "dYA=\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.rootca3.demo.amazontrust.com + // Issuer: CN=Amazon ECDSA 256 M01, O=Amazon, C=US + // Serial number: c458bfaeedae16a5e61fe64773fc898 + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIDTzCCAvWgAwIBAgITBvHXjPDKZM5/VRpvKgcVzA6LUDAKBggqhkjOPQQDAjBG\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + - "Q0EgM0ExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQwMDFaFw0yMjA0Mjgy\n" + - "MzQwMDFaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + - "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" + - "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" + - "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" + - "JAYDVQQDEx1yZXZva2VkLnNjYTNhLmFtYXpvbnRydXN0LmNvbTBZMBMGByqGSM49\n" + - "AgEGCCqGSM49AwEHA0IABJNl90Jq0wddpFj+JbLtmvGR/1geL5t1tvV406jGpYn2\n" + - "C5lAFjwASFy7pAnazZbfSkIDUU2i2XU0+7Cs+j1S/EOjggEpMIIBJTAOBgNVHQ8B\n" + - "Af8EBAMCB4AwHQYDVR0OBBYEFPhX3dYays5Sps0xTgouLkZzYLg4MB8GA1UdIwQY\n" + - "MBaAFATc4JXl6LlrlKHvjFsxHhN+VZfaMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr\n" + - "BgEFBQcDAjB1BggrBgEFBQcBAQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3Nw\n" + - "LnNjYTNhLmFtYXpvbnRydXN0LmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5z\n" + - "Y2EzYS5hbWF6b250cnVzdC5jb20vc2NhM2EuY2VyMCgGA1UdEQQhMB+CHXJldm9r\n" + - "ZWQuc2NhM2EuYW1hem9udHJ1c3QuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMAoG\n" + - "CCqGSM49BAMCA0gAMEUCICLb16/50S4fOAFafi5lagdx7q6EDPPm596g19eQDMXk\n" + - "AiEAksCMLypRB4t30FABlsEjhVCBIxay0iIer2OcCIrhfEI=\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // EE certificates don't have CRLDP extension - if (!ocspEnabled){ - pathValidator.validate(new String[]{INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); + "MIIEhzCCBC2gAwIBAgIQDEWL+u7a4WpeYf5kdz/ImDAKBggqhkjOPQQDAjA9MQsw\n" + + "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + + "U0EgMjU2IE0wMTAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC8xLTAr\n" + + "BgNVBAMTJHJldm9rZWQucm9vdGNhMy5kZW1vLmFtYXpvbnRydXN0LmNvbTBZMBMG\n" + + "ByqGSM49AgEGCCqGSM49AwEHA0IABAsSs5kW5TZlS0SDrMb9iUQAqEaKa12Fc6SN\n" + + "9UR6qtOFdW/1UuziDq3Hl5dqsAYZJkbJSPCIsD2HTP/EGTMKITCjggMbMIIDFzAf\n" + + "BgNVHSMEGDAWgBRPWfy8BhYov6LI2wj7zxMkumlCXDAdBgNVHQ4EFgQUeE55ET2e\n" + + "i8KbY7KHTxOuvCkRpTowTgYDVR0RBEcwRYIkcmV2b2tlZC5yb290Y2EzLmRlbW8u\n" + + "YW1hem9udHJ1c3QuY29tgh1yZXZva2VkLnNjYTNhLmFtYXpvbnRydXN0LmNvbTAO\n" + + "BgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDsG\n" + + "A1UdHwQ0MDIwMKAuoCyGKmh0dHA6Ly9jcmwuZTJtMDEuYW1hem9udHJ1c3QuY29t\n" + + "L2UybTAxLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATB1BggrBgEFBQcBAQRpMGcw\n" + + "LQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLmUybTAxLmFtYXpvbnRydXN0LmNvbTA2\n" + + "BggrBgEFBQcwAoYqaHR0cDovL2NydC5lMm0wMS5hbWF6b250cnVzdC5jb20vZTJt\n" + + "MDEuY2VyMAwGA1UdEwEB/wQCMAAwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB2\n" + + "AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABiAe9lQ8AAAQDAEcw\n" + + "RQIgZVFAX5WPZRBpEOqk620v4Rbzxh/3wrJ5QBMBJ0Mb8B0CIQC0oxFVLfs+PAv7\n" + + "25wawOu2VgDXG9lJAJtCwk3gN8BshQB2AEiw42vapkc0D+VqAvqdMOscUgHLVt0s\n" + + "gdm7v6s52IRzAAABiAe9lQ4AAAQDAEcwRQIhAIPVMj6IfjAUKeGYbpG9s0DRdWbc\n" + + "b8OzsOf+kRqk03NMAiB777hfoFCUMPrN0g8o5v6zp3T3qOhRnYY0TZN4q4NnMgB1\n" + + "ANq2v2s/tbYin5vCu1xr6HCRcWy7UYSFNL2kPTBI1/urAAABiAe9lN4AAAQDAEYw\n" + + "RAIgL0qoVbKLFD+Y3f/V6Rw+euZrPO6d1HEVPQGo7wLzkl8CIGHp3PQmmrEofl76\n" + + "4da7bY0L+csFW0sB8clN0KziMfe6MAoGCCqGSM49BAMCA0gAMEUCIQC+6VdX9X5g\n" + + "x3NSUmJ7py01Zxf26TNBv1ildxqesvZ/7wIgIrefriRzPiIFDHCUbdjk0VlmMwZR\n" + + "VzXXHINsGCiCKOs=\n" + + "-----END CERTIFICATE-----"; - return; - } + public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid - pathValidator.validate(new String[]{VALID, INT}, + pathValidator.validate(new String[]{VALID, INT_VALID}, ValidatePathWithParams.Status.GOOD, null, System.out); // Validate Revoked - pathValidator.validate(new String[]{REVOKED, INT}, + pathValidator.validate(new String[]{REVOKED, INT_REVOKED}, ValidatePathWithParams.Status.REVOKED, - "Mon Jan 28 15:40:35 PST 2019", System.out); + "Mon May 15 13:41:22 PDT 2023", System.out); } } class AmazonCA_4 { - // Owner: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US + // Owner: CN=Amazon ECDSA 384 M02, O=Amazon, C=US // Issuer: CN=Amazon Root CA 4, O=Amazon, C=US - // Serial number: 67f94575a8862a9072e3239c37ceba1274e18 - // Valid from: Wed Oct 21 17:00:00 PDT 2015 until: Sat Oct 18 17:00:00 PDT 2025 + // Serial number: 773127dfaa6b9e2b95538aa76dde4307f17c4 + // Valid from: Tue Aug 23 15:36:58 PDT 2022 until: Fri Aug 23 15:36:58 PDT 2030 private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIC+TCCAn6gAwIBAgITBn+UV1qIYqkHLjI5w3zroSdOGDAKBggqhkjOPQQDAzA5\n" + + "MIIDETCCApagAwIBAgITB3MSffqmueK5VTiqdt3kMH8XxDAKBggqhkjOPQQDAzA5\n" + "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" + - "Um9vdCBDQSA0MB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjELMAkG\n" + - "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENBIDRB\n" + - "MQ8wDQYDVQQDEwZBbWF6b24wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASRP0kIW0Ha\n" + - "7+ORvEVhIS5gIgkH66X5W9vBRTX14oG/1elIyI6LbFZ+E5KAufL0XoWJGI1WbPRm\n" + - "HW246FKSzF0wOEZZyxEROz6tuaVsnXRHRE76roS/Wr064uJpKH+Lv+SjggE5MIIB\n" + - "NTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQU\n" + - "pSHN2+tTIZmqytlnQpQlsnv0wuMwHwYDVR0jBBgwFoAU0+zHOmVuzOHadppW+5zz\n" + - "hm1X5YEwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5y\n" + - "b290Y2E0LmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5y\n" + - "b290Y2E0LmFtYXpvbnRydXN0LmNvbS9yb290Y2E0LmNlcjA/BgNVHR8EODA2MDSg\n" + - "MqAwhi5odHRwOi8vY3JsLnJvb3RjYTQuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTQu\n" + - "Y3JsMBEGA1UdIAQKMAgwBgYEVR0gADAKBggqhkjOPQQDAwNpADBmAjEA59RAOBaj\n" + - "uh0rT/OOTWPEv6TBnb9XEadburBaXb8SSrR8il+NdkfS9WXRAzbwrG7LAjEA3ukD\n" + - "1HrQq+WXHBM5sIuViJI/Zh7MOjsc159Q+dn36PBqLRq03AXqE/lRjnv8C5nj\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=good.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US - // Serial number: 703e4ec57c72d5669efbc98875c3f6bc3f934 - // Valid from: Mon Jul 29 16:55:17 PDT 2019 until: Sat Aug 29 16:55:17 PDT 2020 + "Um9vdCBDQSA0MB4XDTIyMDgyMzIyMzY1OFoXDTMwMDgyMzIyMzY1OFowPTELMAkG\n" + + "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEdMBsGA1UEAxMUQW1hem9uIEVDRFNB\n" + + "IDM4NCBNMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATNYzWQDXV0NoNmR0hJPwJq\n" + + "hjYOOS9z0B2Z7MQudxg5x3Vsib6N+tJkq8dljRq5o6K0bbh/kRVfoi9wfKhB03Yz\n" + + "gkerrwRCH7Z9gU5nbBY+Y5+EtImq4yOB0n7JQgQxWemjggFaMIIBVjASBgNVHRMB\n" + + "Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcD\n" + + "AQYIKwYBBQUHAwIwHQYDVR0OBBYEFKbZqzuHmTP/6Gj4i2GDbNCyuq+9MB8GA1Ud\n" + + "IwQYMBaAFNPsxzplbszh2naaVvuc84ZtV+WBMHsGCCsGAQUFBwEBBG8wbTAvBggr\n" + + "BgEFBQcwAYYjaHR0cDovL29jc3Aucm9vdGNhNC5hbWF6b250cnVzdC5jb20wOgYI\n" + + "KwYBBQUHMAKGLmh0dHA6Ly9jcnQucm9vdGNhNC5hbWF6b250cnVzdC5jb20vcm9v\n" + + "dGNhNC5jZXIwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC5yb290Y2E0LmFt\n" + + "YXpvbnRydXN0LmNvbS9yb290Y2E0LmNybDATBgNVHSAEDDAKMAgGBmeBDAECATAK\n" + + "BggqhkjOPQQDAwNpADBmAjEA2zCG6x0xMlgSXWEGLN8+1XN+OCYF5vj0Z1jtVy+A\n" + + "pdLlzuxNt9HBWn3hvqvO2W8KAjEApNdsZOCmk5uZBYiuCSBnDH3jyKhN6dWyuuHW\n" + + "9Wj7SxKnOU5+wYWZA0BQAv1KT62i\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=valid.rootca4.demo.amazontrust.com + // Issuer: CN=Amazon ECDSA 384 M02, O=Amazon, C=US + // Serial number: f579bed3369f1a147ea5d0e8e6532d3 + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIDxTCCA0qgAwIBAgITBwPk7FfHLVZp77yYh1w/a8P5NDAKBggqhkjOPQQDAzBG\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + - "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTA3MjkyMzU1MTdaFw0yMDA4Mjky\n" + - "MzU1MTdaMIHaMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + - "CERlbGF3YXJlMR0wGwYDVQQPExRQcml2YXRlIE9yZ2FuaXphdGlvbjEQMA4GA1UE\n" + - "BRMHNTg0Njc0MzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO\n" + - "BgNVBAcTB1NlYXR0bGUxHjAcBgNVBAoTFUFtYXpvbiBUcnVzdCBTZXJ2aWNlczEj\n" + - "MCEGA1UEAxMaZ29vZC5zY2E0YS5hbWF6b250cnVzdC5jb20wdjAQBgcqhkjOPQIB\n" + - "BgUrgQQAIgNiAAS9fqMYfOBsdXMSsPjqOlTgIGOlOQWA7Wg6XwVvHTr0+UN+XTeC\n" + - "yZN+XjLbEDQ0CF5eryRZ535sDpwh3qNe0lYFO1n1+2iDtDI1jhhLNYNxBpVnR2BU\n" + - "2l9EuRmgRbQpDCajggFjMIIBXzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFMd0\n" + - "itH5IcE6DpM1uTSBV/6DLmK7MB8GA1UdIwQYMBaAFKUhzdvrUyGZqsrZZ0KUJbJ7\n" + - "9MLjMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BggrBgEFBQcBAQRp\n" + - "MGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnNjYTRhLmFtYXpvbnRydXN0LmNv\n" + - "bTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5zY2E0YS5hbWF6b250cnVzdC5jb20v\n" + - "c2NhNGEuY2VyMCUGA1UdEQQeMByCGmdvb2Quc2NhNGEuYW1hem9udHJ1c3QuY29t\n" + - "MFAGA1UdIARJMEcwDQYLYIZIAYb9bgEHGAMwNgYFZ4EMAQEwLTArBggrBgEFBQcC\n" + - "ARYfaHR0cHM6Ly93d3cuYW1hem9udHJ1c3QuY29tL2NwczAKBggqhkjOPQQDAwNp\n" + - "ADBmAjEA2RBD1F+rnm394VkqA3ncysM3deoyfWqaoAO5923MNisswPnHfVqnfeXf\n" + - "ZwTAvVTBAjEAiiaPx9GRjEk8IBKvCSbTp9rPogVTN7zDDQGrwA83O0pRP7A0dxtT\n" + - "pn/0K5Sj8otp\n" + - "-----END CERTIFICATE-----"; - - // Owner: CN=revoked.sca4a.amazontrust.com, O=Amazon Trust Services, L=Seattle, ST=Washington, C=US, \ - // SERIALNUMBER=5846743, OID.2.5.4.15=PrivateOrganization, OID.1.3.6.1.4.1.311.60.2.1.2=Delaware, \ - // OID.1.3.6.1.4.1.311.60.2.1.3=US - // Issuer: CN=Amazon, OU=Server CA 4A, O=Amazon, C=US - // Serial number: 6f1d79295c384a699d51c2d756bd46213b5b3 - // Valid from: Mon Jan 28 15:41:16 PST 2019 until: Thu Apr 28 16:41:16 PDT 2022 + "MIIEvjCCBESgAwIBAgIQD1eb7TNp8aFH6l0OjmUy0zAKBggqhkjOPQQDAzA9MQsw\n" + + "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + + "U0EgMzg0IE0wMjAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC0xKzAp\n" + + "BgNVBAMTInZhbGlkLnJvb3RjYTQuZGVtby5hbWF6b250cnVzdC5jb20wdjAQBgcq\n" + + "hkjOPQIBBgUrgQQAIgNiAAT6/95JFuvx5t9MVeRZmBtXq63Q2fXZnSwEy2U2F4Qc\n" + + "ejhDwcYfD2HmT6S6GrKqLNJMa5n2YOvet4LZpKJLFF+BQo6FJt5cXkzHHxZ1I4z3\n" + + "8pGU79CpCgFOFy6QUlF68NajggMXMIIDEzAfBgNVHSMEGDAWgBSm2as7h5kz/+ho\n" + + "+Ithg2zQsrqvvTAdBgNVHQ4EFgQUR/GnpQkrUsCj8jF6/JIE1Rs07zswSQYDVR0R\n" + + "BEIwQIIidmFsaWQucm9vdGNhNC5kZW1vLmFtYXpvbnRydXN0LmNvbYIaZ29vZC5z\n" + + "Y2E0YS5hbWF6b250cnVzdC5jb20wDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQG\n" + + "CCsGAQUFBwMBBggrBgEFBQcDAjA7BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3Js\n" + + "LmUzbTAyLmFtYXpvbnRydXN0LmNvbS9lM20wMi5jcmwwEwYDVR0gBAwwCjAIBgZn\n" + + "gQwBAgEwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5l\n" + + "M20wMi5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuZTNt\n" + + "MDIuYW1hem9udHJ1c3QuY29tL2UzbTAyLmNlcjAMBgNVHRMBAf8EAjAAMIIBfgYK\n" + + "KwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVct520zROiModGfLzs3sNR\n" + + "SFlGcR+1mwAAAYgHvZA9AAAEAwBHMEUCIQCmzmQOzunsuAg1GpIcNx0isG6ylbhP\n" + + "y9JP4UFclL2hdwIgBtTM89mE7QJDj7h7xr2eRPio1ehgmeYH1PHXxCqHIGYAdgBI\n" + + "sONr2qZHNA/lagL6nTDrHFIBy1bdLIHZu7+rOdiEcwAAAYgHvZB1AAAEAwBHMEUC\n" + + "IF9hbi82CLU5umfRze4NpX6u4jlT+N8KSaBe6UbhqjBZAiEAi2Y6PTt2+107LxtM\n" + + "oBpHprph7hQvGfjPE+p+rfM/X+EAdgDatr9rP7W2Ip+bwrtca+hwkXFsu1GEhTS9\n" + + "pD0wSNf7qwAAAYgHvZBeAAAEAwBHMEUCIAI+m4mVE3HtZOEMC5VI7m0nEPdPPJUq\n" + + "fxUKPpeIVmk5AiEA0scVJy7g3Fv+2nTVhbcwWCwn/Gvc+0txQrc529juflcwCgYI\n" + + "KoZIzj0EAwMDaAAwZQIxAKV837BpqlNHg35EsCCtrJPoQ6RuY9UoHm1O2CdsCXGR\n" + + "Z3kAnlgIV8A/waI6wQqfsQIwdCqaC+qN60JCnX09YKRD15eQjq1rN3w+llI+lEbS\n" + + "FSMsnoHJcqMZLo9s+4Rf0zS3\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=revoked.rootca4.demo.amazontrust.com + // Issuer: CN=Amazon ECDSA 384 M02, O=Amazon, C=US + // Serial number: 4a5d392936b4decb818b7fb106ebbd8 + // Valid from: Tue May 09 17:00:00 PDT 2023 until: Fri Jun 07 16:59:59 PDT 2024 private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIDjTCCAxKgAwIBAgITBvHXkpXDhKaZ1RwtdWvUYhO1szAKBggqhkjOPQQDAzBG\n" + - "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRUwEwYDVQQLEwxTZXJ2ZXIg\n" + - "Q0EgNEExDzANBgNVBAMTBkFtYXpvbjAeFw0xOTAxMjgyMzQxMTZaFw0yMjA0Mjgy\n" + - "MzQxMTZaMIHcMRMwEQYLKwYBBAGCNzwCAQMTAlVTMRkwFwYLKwYBBAGCNzwCAQIT\n" + - "CERlbGF3YXJlMRwwGgYDVQQPExNQcml2YXRlT3JnYW5pemF0aW9uMRAwDgYDVQQF\n" + - "Ewc1ODQ2NzQzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G\n" + - "A1UEBxMHU2VhdHRsZTEeMBwGA1UEChMVQW1hem9uIFRydXN0IFNlcnZpY2VzMSYw\n" + - "JAYDVQQDEx1yZXZva2VkLnNjYTRhLmFtYXpvbnRydXN0LmNvbTB2MBAGByqGSM49\n" + - "AgEGBSuBBAAiA2IABLuNpZTcNU3FElNP3Y/OeXIZcIMXkFTBi/n92fNwHfqUbEhH\n" + - "H+PovJ26eAGvb5a8bGc275MBFcVnWL0rCVgM+j9KAtBDCRJX3f7mo0D2VKcmtZKu\n" + - "jPxwGPy2kuqM505dGqOCASkwggElMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQU\n" + - "zUFIhn+hphzCKA2qgAdLztSBzJgwHwYDVR0jBBgwFoAUpSHN2+tTIZmqytlnQpQl\n" + - "snv0wuMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGCCsGAQUFBwEB\n" + - "BGkwZzAtBggrBgEFBQcwAYYhaHR0cDovL29jc3Auc2NhNGEuYW1hem9udHJ1c3Qu\n" + - "Y29tMDYGCCsGAQUFBzAChipodHRwOi8vY3J0LnNjYTRhLmFtYXpvbnRydXN0LmNv\n" + - "bS9zY2E0YS5jZXIwKAYDVR0RBCEwH4IdcmV2b2tlZC5zY2E0YS5hbWF6b250cnVz\n" + - "dC5jb20wEwYDVR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwMDaQAwZgIxALDA\n" + - "klY3iKwyzwpwVtLfLxzQEl45xvE2VjBJvfJJ60KhJt7Ud0gt0zxkogh29+mpEQIx\n" + - "ANTG1mk8OJB41DU7ru1Pwc6ju8STw1FdwDp/Eliqhvnm2i0k4/F1bBHLta2mlC2V\n" + - "hg==\n" + - "-----END CERTIFICATE-----"; - - public void runTest(ValidatePathWithParams pathValidator, boolean ocspEnabled) throws Exception { - // EE certificates don't have CRLDP extension - if (!ocspEnabled){ - pathValidator.validate(new String[]{INT}, - ValidatePathWithParams.Status.GOOD, null, System.out); + "MIIExjCCBEygAwIBAgIQBKXTkpNrTey4GLf7EG672DAKBggqhkjOPQQDAzA9MQsw\n" + + "CQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMR0wGwYDVQQDExRBbWF6b24gRUNE\n" + + "U0EgMzg0IE0wMjAeFw0yMzA1MTAwMDAwMDBaFw0yNDA2MDcyMzU5NTlaMC8xLTAr\n" + + "BgNVBAMTJHJldm9rZWQucm9vdGNhNC5kZW1vLmFtYXpvbnRydXN0LmNvbTB2MBAG\n" + + "ByqGSM49AgEGBSuBBAAiA2IABFYfMbv5/vgqDunZj4ffJiuELtdwfEPXx9QlZnCm\n" + + "rBP3Z4/GvUVRVmyh5sYdnbCGCEClH/RxU6BC5SKv+TzhsFLEumhezanljnQXRAIL\n" + + "a1OGbP8zLLP6FuAD0cjY3P3adKOCAx0wggMZMB8GA1UdIwQYMBaAFKbZqzuHmTP/\n" + + "6Gj4i2GDbNCyuq+9MB0GA1UdDgQWBBSqnGV5pN/agPCtVdV37CP1z/DUqjBOBgNV\n" + + "HREERzBFgiRyZXZva2VkLnJvb3RjYTQuZGVtby5hbWF6b250cnVzdC5jb22CHXJl\n" + + "dm9rZWQuc2NhNGEuYW1hem9udHJ1c3QuY29tMA4GA1UdDwEB/wQEAwIHgDAdBgNV\n" + + "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwOwYDVR0fBDQwMjAwoC6gLIYqaHR0\n" + + "cDovL2NybC5lM20wMi5hbWF6b250cnVzdC5jb20vZTNtMDIuY3JsMBMGA1UdIAQM\n" + + "MAowCAYGZ4EMAQIBMHUGCCsGAQUFBwEBBGkwZzAtBggrBgEFBQcwAYYhaHR0cDov\n" + + "L29jc3AuZTNtMDIuYW1hem9udHJ1c3QuY29tMDYGCCsGAQUFBzAChipodHRwOi8v\n" + + "Y3J0LmUzbTAyLmFtYXpvbnRydXN0LmNvbS9lM20wMi5jZXIwDAYDVR0TAQH/BAIw\n" + + "ADCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYAdv+IPwq2+5VRwmHM9Ye6NLSk\n" + + "zbsp3GhCCp/mZ0xaOnQAAAGIB72QJQAABAMARzBFAiA74zKrlL+y5rYwSLxBL8fs\n" + + "QYRYXF0s0sGoaSEeAg1DkgIhAPu8Z0TLIFoppmyiv+A5z6S+SG+v/kOsAYmQmiUO\n" + + "5scIAHcASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGIB72QJgAA\n" + + "BAMASDBGAiEAg+x7JBT3oIaZdnfgGN1G6SAiNUL7zR/tBhbWIG9tz94CIQDGwBiV\n" + + "Tslt11+W3ZaNsS7UtUIiB45YHUc4qKm5ry2fTAB2ANq2v2s/tbYin5vCu1xr6HCR\n" + + "cWy7UYSFNL2kPTBI1/urAAABiAe9kAgAAAQDAEcwRQIgPvKfSpMJKRocGk9+GNr3\n" + + "hUj8x8WySB//0X116TNgA0gCIQDhGRqxnEZmEFGEfj5GY9vjEfm0kKwcL0lCuwBu\n" + + "NZG4dzAKBggqhkjOPQQDAwNoADBlAjEA1PLdsrko3tDs50aAeEU9Gn+0CG8QKy7R\n" + + "fQaXBTjGETDgGJk/7zGNpGelKPr/UYV9AjASwdA32S8jIADxA8HrqiMsVYDFMnbU\n" + + "jLLwR6CTLtAcWtwVmoQ2x0usvTvN8YJBPoA=\n" + + "-----END CERTIFICATE-----"; - return; - } + public void runTest(ValidatePathWithParams pathValidator) throws Exception { // Validate valid pathValidator.validate(new String[]{VALID, INT}, @@ -547,6 +608,6 @@ // Validate Revoked pathValidator.validate(new String[]{REVOKED, INT}, ValidatePathWithParams.Status.REVOKED, - "Mon Jan 28 15:41:53 PST 2019", System.out); + "Mon May 15 13:42:48 PDT 2023", System.out); } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java --- openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java 1970-01-01 00:00:00.000000000 +0000 @@ -1,227 +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. - */ - -/* - * @test - * @bug 8245654 - * @summary Interoperability tests with Certigna Root CA from Dhimyotis - * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath CertignaCA OCSP - * @run main/othervm -Djava.security.debug=certpath CertignaCA CRL - */ - -/* - * Obtain TLS test artifacts for Certigna Root CA from: - * - * Valid TLS Certificates: - * https://valid.servicesca.dhimyotis.com/ - * - * Revoked TLS Certificates: - * https://revoked.servicesca.dhimyotis.com/ - */ -public class CertignaCA { - - // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, - // OU=0002 48146308100036, O=DHIMYOTIS, C=FR - // Issuer: CN=Certigna, O=Dhimyotis, C=FR - // Serial number: 6f82fa28acd6f784bb5b120ba87367ad - // Valid from: Wed Nov 25 03:33:52 PST 2015 until: Sat Nov 22 03:33:52 PST 2025 - private static final String INT = "-----BEGIN CERTIFICATE-----\n" + - "MIIGFjCCBP6gAwIBAgIQb4L6KKzW94S7WxILqHNnrTANBgkqhkiG9w0BAQsFADA0\n" + - "MQswCQYDVQQGEwJGUjESMBAGA1UECgwJRGhpbXlvdGlzMREwDwYDVQQDDAhDZXJ0\n" + - "aWduYTAeFw0xNTExMjUxMTMzNTJaFw0yNTExMjIxMTMzNTJaMH0xCzAJBgNVBAYT\n" + - "AkZSMRIwEAYDVQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgx\n" + - "MDAwMzYxHTAbBgNVBGEMFE5UUkZSLTQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQQDDBRD\n" + - "ZXJ0aWduYSBTZXJ2aWNlcyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" + - "ggIBALPM+7LpWBz9wFcPaTc3xnB+5g0XrnptB0EPPfrR04vO52Ykm4ky1d4ZLd10\n" + - "tbM1fa1RqNSOVWWg93O4pL7zCFKlz6JV74ZZVhHpEAwzBwv2oPnxvVbxtSN67xsS\n" + - "Y66ahUYxjzs8+3FhmsiRxqwnTYvK2u70uglUvRisOKyTL/M6JnrC4y8tlmoz7OSa\n" + - "5BmBMVplJFQtvmON6N9aHLvYMz+EyJPCbXL6pELxeHjFT5QmIaRamsr2DOTaCjtB\n" + - "ZKI1Wnh3X7lnbjM8MESJiV2t7E9tIQNG0Z/HI3tO4aaUMum3KysY5sC8v3vi7rry\n" + - "GidgzHQhrtP0ZXWW5UH/k7umLS/P/XXWnCFpc2Lxa1uDGfc2im7xibRoPP+JNZsz\n" + - "N76euFlls6jyEXAiwnVr14tVVTewLK0OWs5SJHpEKp8PGMZRDj59EmMvokWwzL6Q\n" + - "zNZ6vVAp00oOm05sbspNY9+MFqGKKUsKvhFGEa4XmRNxDe6KswLcjPZB+NKHZ0QW\n" + - "Fd4ip5C5XmEK/8qIPjwVr9dah9+oiHGGO8Wx7gJAMF5DTmkvW7GhqCKj1LmHnabj\n" + - "zc8av6kxWVQZi/C7HCm9i/W4wio+JA2EAFLqNL3GPNbK9kau4yPhQt/c7zxzo0OH\n" + - "nlsV4THCG7oOCd3cfCiyfQcb3FBt6OSpaKRZxjCLBwP00r0fAgMBAAGjggHZMIIB\n" + - "1TASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU\n" + - "rOyGj0s3HLh/FxsZ0K7oTuM0XBIwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF\n" + - "9lo53BGhOKQ2MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAP\n" + - "BgNVBAMMCENlcnRpZ25hggkA/tzjAQ/JSP8wSQYDVR0gBEIwQDA+BgoqgXoBgTEB\n" + - "AAECMDAwLgYIKwYBBQUHAgEWImh0dHBzOi8vd3d3LmNlcnRpZ25hLmZyL2F1dG9y\n" + - "aXRlcy8wfAYIKwYBBQUHAQEEcDBuMDQGCCsGAQUFBzAChihodHRwOi8vYXV0b3Jp\n" + - "dGUuY2VydGlnbmEuZnIvY2VydGlnbmEuZGVyMDYGCCsGAQUFBzAChipodHRwOi8v\n" + - "YXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5kZXIwYQYDVR0fBFowWDAp\n" + - "oCegJYYjaHR0cDovL2NybC5jZXJ0aWduYS5mci9jZXJ0aWduYS5jcmwwK6ApoCeG\n" + - "JWh0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5jcmwwDQYJKoZIhvcN\n" + - "AQELBQADggEBAGLft7gIuGPZVfg0cTM+HT2xAZFPDb/2+siH06x+dH044zMKbBIN\n" + - "bRzhKipwB1A3MW8FQjveE9tyrfyuqZE/X+o2SlGcdNV44ybYkxo4f6kcLEavV/IW\n" + - "+oFEnojZlhpksYcxrvQoEyqkAwshe8IS2KtZHKVACrt+XSs0lwvy7ALGmHaF7A4b\n" + - "y6cZWItA7Lhj8XWp+8tBJDj7HocRbWtxzEODdBuyMgJzFrNjc+97J0vH/K0+3yjm\n" + - "kczpKshMA0tM+MF9XDMN/MuwrPmUWGO/fHiqHgUp8yqeWtl1n44ZxkkK1t9GRwhn\n" + - "DWLv73/xhTmdhWYQ/reo0GbgBoLiltKmIJQ=\n" + - "-----END CERTIFICATE-----"; - - // Owner: SERIALNUMBER=S230100953, CN=valid.servicesca.dhimyotis.com, - // OU=0002 48146308100036, O=DHIMYOTIS, L=VILLENEUVE D'ASCQ, C=FR - // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, - // OU=0002 48146308100036, O=DHIMYOTIS, C=FR - // Serial number: 2959798fe2e0e7b43810169ae938bc5f - // Valid from: Sun Mar 13 16:00:00 PDT 2022 until: Mon Mar 13 15:59:59 PDT 2023 - private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + - "MIIIkzCCBnugAwIBAgIQKVl5j+Lg57Q4EBaa6Ti8XzANBgkqhkiG9w0BAQsFADB9\n" + - "MQswCQYDVQQGEwJGUjESMBAGA1UECgwJREhJTVlPVElTMRwwGgYDVQQLDBMwMDAy\n" + - "IDQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQRhDBROVFJGUi00ODE0NjMwODEwMDAzNjEd\n" + - "MBsGA1UEAwwUQ2VydGlnbmEgU2VydmljZXMgQ0EwHhcNMjIwMzEzMjMwMDAwWhcN\n" + - "MjMwMzEzMjI1OTU5WjCBmTELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + - "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgx\n" + - "NDYzMDgxMDAwMzYxJzAlBgNVBAMMHnZhbGlkLnNlcnZpY2VzY2EuZGhpbXlvdGlz\n" + - "LmNvbTETMBEGA1UEBRMKUzIzMDEwMDk1MzCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" + - "ADCCAQoCggEBALpeGHbzRGnv1C0PdJS0nT+Cx98Pw8ctaw51m9Vlk2j8AFGZRu8r\n" + - "lX3noQYX0AIfcbk6KqPAreIvJQV0UgM5jxt3mIQF7iU+55MG4mWmSJgKDDq4b3ck\n" + - "WdBy0KpSBqLmB9sHyTNk9NilNu7VwG03HGIltWA2uQFJGC8CkxwAFpMCQ9RVYw2Z\n" + - "NkL/SsiPgrRLiCJZjesk1oAcLnLp7hbelfUB2Z71VmuDDlom7CsLvdN8eIG+Lj+V\n" + - "wkGmH6AbVGvbFniFDLCNDSJWCQ9AHeO+i0CM/wd2gBRSgm993p2YMxu5mVZjz/rp\n" + - "ELaCYjulvNZKvPIFoNe8qsxlXRWeqWaHuPsCAwEAAaOCA/AwggPsMIHkBggrBgEF\n" + - "BQcBAQSB1zCB1DA4BggrBgEFBQcwAoYsaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rp\n" + - "cy5jb20vc2VydmljZXNjYS5kZXIwNgYIKwYBBQUHMAKGKmh0dHA6Ly9hdXRvcml0\n" + - "ZS5jZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmRlcjAwBggrBgEFBQcwAYYkaHR0cDov\n" + - "L3NlcnZpY2VzY2Eub2NzcC5kaGlteW90aXMuY29tMC4GCCsGAQUFBzABhiJodHRw\n" + - "Oi8vc2VydmljZXNjYS5vY3NwLmNlcnRpZ25hLmZyMB8GA1UdIwQYMBaAFKzsho9L\n" + - "Nxy4fxcbGdCu6E7jNFwSMAkGA1UdEwQCMAAwYQYDVR0gBFowWDAIBgZngQwBAgIw\n" + - "TAYLKoF6AYExAgUBAQEwPTA7BggrBgEFBQcCARYvaHR0cHM6Ly93d3cuY2VydGln\n" + - "bmEuY29tL2F1dG9yaXRlLWNlcnRpZmljYXRpb24wZQYDVR0fBF4wXDAroCmgJ4Yl\n" + - "aHR0cDovL2NybC5jZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmNybDAtoCugKYYnaHR0\n" + - "cDovL2NybC5kaGlteW90aXMuY29tL3NlcnZpY2VzY2EuY3JsMBMGA1UdJQQMMAoG\n" + - "CCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIFoDBIBgNVHREEQTA/gh12YWxpZC5zZXJ2\n" + - "aWNlc2NhLmNlcnRpZ25hLmNvbYIedmFsaWQuc2VydmljZXNjYS5kaGlteW90aXMu\n" + - "Y29tMB0GA1UdDgQWBBSGQwwMIdxiI7P+CFU/Z968XZaSGzCCAX0GCisGAQQB1nkC\n" + - "BAIEggFtBIIBaQFnAHUArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgooA\n" + - "AAF/h9eOGgAABAMARjBEAiBaneK2CTn9lH28CUnL2C2/WklUYkvygMiDrtCIUXfw\n" + - "gQIgJrGxwgGlsYzUdZyZY/oNWSLByO8/Jb5LXbNibdk5SnAAdwDoPtDaPvUGNTLn\n" + - "Vyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAX+H14/NAAAEAwBIMEYCIQCVtuV9p/Ug\n" + - "IhwVoMUjPp1KzGte/FmDaKPx432VjOpD+AIhANKWkDEuVnMzPH8sdJCL+eXoB0Q7\n" + - "0mpe5dHEiFJS8lTBAHUAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZoA\n" + - "AAF/h9eTcQAABAMARjBEAiAjdYhnzPe9lJksk94ngl7PLDRi71tSRN7SslibEyv+\n" + - "XAIgLQ5NKQAaJnF8oA7WnHB8gyJ/8kqZi52d1WFgARDLR30wDQYJKoZIhvcNAQEL\n" + - "BQADggIBAJhLhW5Gh9yOPKsrMhABd7U5juc5ev97c6s7Az70Yr5/EtH6TlgC6a1N\n" + - "i0yzFOeXzAR8Svsq6HzqP9kMJkEFIrdWH8JZdEv871EjYetEzLLnO0m+dNEROJAh\n" + - "fcJ2w2LufPNaQ327tGY/DxDH9jdtgquReO01bPlJ0Yc5J3maz4XapeUm/kQ8dRzS\n" + - "0UBOxfUlEMpDatZzg7wugy7g9vOndW/VbtbN5Iioq2bjuykPJZfZUx4cCAmLUS7w\n" + - "bqPThQ54PnybiPXaF8cH1Gq0Rs/lGB1erzRXRXHgMy61mFY944r13oATnSdTy8Gm\n" + - "QoMsVp9w7WBRo8O4PR606Ke8Ufm9Kg2GJ1sHClf70FNFO/OSFlr3BLDG0vEMdgVW\n" + - "9QLu6UQXa9PhWMoo030k5fmUySzIUljXnstj3rgcD2HE1UrobTqyRHbbQ8JVWaF0\n" + - "PrPR4WDFI9dY0jixVQucKlX6FCqsyNrJF8GWDlZH+Cd8bk+MA9fKUuX/vmoOc2d+\n" + - "bvOCliME7YjAJkyclk6yiFIMnqyh+TD0d8WbjE94YC/293Xqb6WGkRhhsCX9RUrk\n" + - "I6QbS2uicCFGjRsPmjvMkDDxS00MShRl2K/KpsAx68Cv/Gcw3bv31obwNXTB2IBg\n" + - "gI0MfBHnjIp1nmNvCNmVIP52YrGQyC2JE7+GZUWTuwUVeDgBhiEZ\n" + - "-----END CERTIFICATE-----"; - - // Owner: SERIALNUMBER=S230120951, CN=revoked.servicesca.dhimyotis.com, - // OU=0002 48146308100036, O=DHIMYOTIS, L=VILLENEUVE D'ASCQ, C=FR - // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, - // OU=0002 48146308100036, O=DHIMYOTIS, C=FR - // Serial number: f88f2566b3dbf73763622db9b2bf9cc - // Valid from: Sun Mar 13 16:00:00 PDT 2022 until: Mon Mar 13 15:59:59 PDT 2023 - private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + - "MIIImTCCBoGgAwIBAgIQD4jyVms9v3N2NiLbmyv5zDANBgkqhkiG9w0BAQsFADB9\n" + - "MQswCQYDVQQGEwJGUjESMBAGA1UECgwJREhJTVlPVElTMRwwGgYDVQQLDBMwMDAy\n" + - "IDQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQRhDBROVFJGUi00ODE0NjMwODEwMDAzNjEd\n" + - "MBsGA1UEAwwUQ2VydGlnbmEgU2VydmljZXMgQ0EwHhcNMjIwMzEzMjMwMDAwWhcN\n" + - "MjMwMzEzMjI1OTU5WjCBmzELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + - "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgx\n" + - "NDYzMDgxMDAwMzYxKTAnBgNVBAMMIHJldm9rZWQuc2VydmljZXNjYS5kaGlteW90\n" + - "aXMuY29tMRMwEQYDVQQFEwpTMjMwMTIwOTUxMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" + - "AQ8AMIIBCgKCAQEAouvIzemKChCjYICW+TzRigLkqaTdMLnaPlGaXyCCoEUS6nkK\n" + - "QnrwTgebf1X9/mwSAuvTo3Ck7CVgE8AMqsPTluSjezCJuED/F3HYy2YsbIhnVK/i\n" + - "uSzKsDGVY3RlVNm2MA2viVTNBbOFhk4kefYqpDCmp3EGvIDOCb7Y5PTuKKQ79s97\n" + - "uDm+0WoBnOdwSuZMUg+hvINBgu2JQFwiWP0g/SxoK6Ci9SVokM3zR4KgECkMVArf\n" + - "cH0dN+5SYvByaGegQJy7TdKqDsf1lIHM19tUXcxOBNRgV3Rf7WMNIlERtLXjRfke\n" + - "IWXf8QtXRVIH/i/PoVTDo2qvQOMnZFY/Eb5dFQIDAQABo4ID9DCCA/AwgeQGCCsG\n" + - "AQUFBwEBBIHXMIHUMDgGCCsGAQUFBzAChixodHRwOi8vYXV0b3JpdGUuZGhpbXlv\n" + - "dGlzLmNvbS9zZXJ2aWNlc2NhLmRlcjA2BggrBgEFBQcwAoYqaHR0cDovL2F1dG9y\n" + - "aXRlLmNlcnRpZ25hLmZyL3NlcnZpY2VzY2EuZGVyMDAGCCsGAQUFBzABhiRodHRw\n" + - "Oi8vc2VydmljZXNjYS5vY3NwLmRoaW15b3Rpcy5jb20wLgYIKwYBBQUHMAGGImh0\n" + - "dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuY2VydGlnbmEuZnIwHwYDVR0jBBgwFoAUrOyG\n" + - "j0s3HLh/FxsZ0K7oTuM0XBIwCQYDVR0TBAIwADBhBgNVHSAEWjBYMAgGBmeBDAEC\n" + - "AjBMBgsqgXoBgTECBQEBATA9MDsGCCsGAQUFBwIBFi9odHRwczovL3d3dy5jZXJ0\n" + - "aWduYS5jb20vYXV0b3JpdGUtY2VydGlmaWNhdGlvbjBlBgNVHR8EXjBcMCugKaAn\n" + - "hiVodHRwOi8vY3JsLmNlcnRpZ25hLmZyL3NlcnZpY2VzY2EuY3JsMC2gK6Aphido\n" + - "dHRwOi8vY3JsLmRoaW15b3Rpcy5jb20vc2VydmljZXNjYS5jcmwwEwYDVR0lBAww\n" + - "CgYIKwYBBQUHAwEwDgYDVR0PAQH/BAQDAgWgMEwGA1UdEQRFMEOCH3Jldm9rZWQu\n" + - "c2VydmljZXNjYS5jZXJ0aWduYS5jb22CIHJldm9rZWQuc2VydmljZXNjYS5kaGlt\n" + - "eW90aXMuY29tMB0GA1UdDgQWBBTGIed1eHBS8Z1H3PdMkItpjyjq2TCCAX0GCisG\n" + - "AQQB1nkCBAIEggFtBIIBaQFnAHcArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWG\n" + - "NOvcgooAAAF/h9g4MAAABAMASDBGAiEAp/1fQB730JrX9YGD3d1Uq7rTAL95tMKe\n" + - "G6kgUP1GEWoCIQCzi6feA3cImTH6tVZALNEmve/n8SVFAvD2AvX8ioCD9QB1AOg+\n" + - "0No+9QY1MudXKLyJa8kD08vREWvs62nhd31tBr1uAAABf4fYNHcAAAQDAEYwRAIg\n" + - "Dnd8oOV7/MuaiyR23qbdRVf1kBSsDxnLp1/vRdD0JTYCIAw7LuZalEVa/0KpuNHs\n" + - "NIdUJgV4Vioa2xkb9fdPIhtkAHUAs3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PAD\n" + - "Dnk2pZoAAAF/h9g7nwAABAMARjBEAiA80M1W3V3iKjm6Dwn+hKkmvGiuXZoM6o3f\n" + - "QJsZ2ZOx0QIgUiS3I83WzoCdD4qO9rlmDQhRD69CeVzCgLtkaTPz3JYwDQYJKoZI\n" + - "hvcNAQELBQADggIBADKub0gNyasTvURoYukQCllqDC+SvWA4TURBcmQMNjdVkreJ\n" + - "B3O91HZhTyhrCBJxybeIG89zuRI6rjTpHCQGFqtP7968NA3eUlxGGnAPpw6VbN47\n" + - "Ake+CRI9XnhxcKmTGm987DjtIBH42BedS59P1T56grZP5ysOog9Hz4eYo2ytbZqt\n" + - "P/DHggivymaaiIaBsqup8C7/XN3vVAa/yo1FeLJ48i1d0M9hjGBUFMajd8Y5+pE7\n" + - "p6Nb5mT1LXbetORYXMyG3MiJQPBAr1dLnRGnOZxc1Kxa1QwoAFQAFIXFpqfBwfHi\n" + - "NaSDdFS/wLbpe7UvtC8FWLq9sgITDEkPqDPCsbu8Vc7OxaMhBJ7HQGaAYMReGADG\n" + - "Elx9ffAc+dFR62zFnqMLouaEznZ7FVNmU3cYbrFVBvnGmoDRe0AKUoYv5DCiawUg\n" + - "qeQS69DgG7DOE5VIDaWX2Cevy81mz7O8EVQsyS15J/MUxzWfQpRaHUqkge6G9FSH\n" + - "hF/Nm48oWgpWop5aIF2O6bA/Bt1VvAWdypUPUr4gtpYIQoOQBzTFgBVWUeOTOImE\n" + - "avvpzSwGQfZkB7t5PcAQ+zYGxWq7fr30/qY3geePcXJCGWS6PXyj8lNn4CaJ2sMF\n" + - "GKxNJGD49/5uoxi3b3TzGUn/3eG2qP2RZoXZ6ZPLAo+moIy3XLwMoZm3Im8r\n" + - "-----END CERTIFICATE-----"; - - public static void main(String[] args) throws Exception { - - ValidatePathWithParams pathValidator; - String[] validChainToValidate; - String[] revChainToValidate; - - if (args.length >= 1 && "CRL".equalsIgnoreCase(args[0])) { - pathValidator = new ValidatePathWithParams(null); - pathValidator.enableCRLCheck(); - - validChainToValidate = new String[]{VALID, INT}; - revChainToValidate = new String[]{REVOKED, INT}; - } else { - // OCSP check by default - // int certificate doesn't specify OCSP responder - pathValidator = new ValidatePathWithParams(new String[]{INT}); - pathValidator.enableOCSPCheck(); - - validChainToValidate = new String[]{VALID}; - revChainToValidate = new String[]{REVOKED}; - } - - // Validate valid - pathValidator.validate(validChainToValidate, - ValidatePathWithParams.Status.GOOD, null, System.out); - - // Validate Revoked - pathValidator.validate(revChainToValidate, - ValidatePathWithParams.Status.REVOKED, - "Mon Mar 14 03:00:16 PDT 2022", System.out); - } -} - diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java --- openjdk-lts-11.0.20.1+1/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaRoots.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,293 @@ +/* + * 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 8245654 8314960 + * @summary Interoperability tests with Certigna Root CAs from Dhimyotis + * @build ValidatePathWithParams + * @run main/othervm -Djava.security.debug=certpath CertignaRoots OCSP + * @run main/othervm -Djava.security.debug=certpath CertignaRoots CRL + */ + +/* + * Obtain TLS test artifacts for Certigna Root CAs from: + * + * Valid TLS Certificates: + * https://valid.servicesca.dhimyotis.com/ + * + * Revoked TLS Certificates: + * https://revoked.servicesca.dhimyotis.com/ + */ +public class CertignaRoots { + + // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, + // OU=0002 48146308100036, O=DHIMYOTIS, C=FR + // Issuer: CN=Certigna Root CA, OU=0002 48146308100036, O=Dhimyotis, C=FR + // Serial number: fd30cf04344fc38dd90c4e70753d0623 + // Valid from: Wed Nov 25 03:37:21 PST 2015 until: Fri Jun 03 04:37:21 PDT 2033 + private static final String INT_CERTIGNA_ROOT_CA = "-----BEGIN CERTIFICATE-----\n" + + "MIIHETCCBPmgAwIBAgIRAP0wzwQ0T8ON2QxOcHU9BiMwDQYJKoZIhvcNAQELBQAw\n" + + "WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw\n" + + "MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x\n" + + "NTExMjUxMTM3MjFaFw0zMzA2MDMxMTM3MjFaMH0xCzAJBgNVBAYTAkZSMRIwEAYD\n" + + "VQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxHTAb\n" + + "BgNVBGEMFE5UUkZSLTQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQQDDBRDZXJ0aWduYSBT\n" + + "ZXJ2aWNlcyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALPM+7Lp\n" + + "WBz9wFcPaTc3xnB+5g0XrnptB0EPPfrR04vO52Ykm4ky1d4ZLd10tbM1fa1RqNSO\n" + + "VWWg93O4pL7zCFKlz6JV74ZZVhHpEAwzBwv2oPnxvVbxtSN67xsSY66ahUYxjzs8\n" + + "+3FhmsiRxqwnTYvK2u70uglUvRisOKyTL/M6JnrC4y8tlmoz7OSa5BmBMVplJFQt\n" + + "vmON6N9aHLvYMz+EyJPCbXL6pELxeHjFT5QmIaRamsr2DOTaCjtBZKI1Wnh3X7ln\n" + + "bjM8MESJiV2t7E9tIQNG0Z/HI3tO4aaUMum3KysY5sC8v3vi7rryGidgzHQhrtP0\n" + + "ZXWW5UH/k7umLS/P/XXWnCFpc2Lxa1uDGfc2im7xibRoPP+JNZszN76euFlls6jy\n" + + "EXAiwnVr14tVVTewLK0OWs5SJHpEKp8PGMZRDj59EmMvokWwzL6QzNZ6vVAp00oO\n" + + "m05sbspNY9+MFqGKKUsKvhFGEa4XmRNxDe6KswLcjPZB+NKHZ0QWFd4ip5C5XmEK\n" + + "/8qIPjwVr9dah9+oiHGGO8Wx7gJAMF5DTmkvW7GhqCKj1LmHnabjzc8av6kxWVQZ\n" + + "i/C7HCm9i/W4wio+JA2EAFLqNL3GPNbK9kau4yPhQt/c7zxzo0OHnlsV4THCG7oO\n" + + "Cd3cfCiyfQcb3FBt6OSpaKRZxjCLBwP00r0fAgMBAAGjggGtMIIBqTASBgNVHRMB\n" + + "Af8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrOyGj0s3HLh/\n" + + "FxsZ0K7oTuM0XBIwHwYDVR0jBBgwFoAUGIdW4G537iQ1PE5zmh/W4eJ5fiswSQYD\n" + + "VR0gBEIwQDA+BgoqgXoBgTECAAEBMDAwLgYIKwYBBQUHAgEWImh0dHBzOi8vd3d3\n" + + "LmNlcnRpZ25hLmZyL2F1dG9yaXRlcy8wgYgGCCsGAQUFBwEBBHwwejA6BggrBgEF\n" + + "BQcwAoYuaHR0cDovL2F1dG9yaXRlLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNh\n" + + "LmRlcjA8BggrBgEFBQcwAoYwaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20v\n" + + "Y2VydGlnbmFyb290Y2EuZGVyMG0GA1UdHwRmMGQwL6AtoCuGKWh0dHA6Ly9jcmwu\n" + + "Y2VydGlnbmEuZnIvY2VydGlnbmFyb290Y2EuY3JsMDGgL6AthitodHRwOi8vY3Js\n" + + "LmRoaW15b3Rpcy5jb20vY2VydGlnbmFyb290Y2EuY3JsMA0GCSqGSIb3DQEBCwUA\n" + + "A4ICAQCI5QbprXJ93L+JWHYpUTinXAMSvXMx2dmNm4mIiJRAbGnBOoEYx7M61fbL\n" + + "L5EJIYZhw8jLmeYVFuMao5OJLwda+RMmVzE7lyTGsY64IDKdwogByNCqbKzrlhnU\n" + + "8myyMNB0BDs2jgwQe2Dj9v+MddeHr7sDqvs7R1tSS5hoASLtdQhO7oxUzr3m7M8q\n" + + "+lh4jszli+cjfiPUVS2ADFu4ccQIh4OsIX6SWdU+8R+c/fn0FV6ip4SAVbNyCToz\n" + + "0ZbZKO8YTJgORxRmvrop9dPyuLWjaRrZ0LMx4a3EM3sQDPDqmsG0lHtfFj2PiJvq\n" + + "4lEYA+gDiLKODI+3DJMqo559m3QSS52DsShomHX/Txd0lJoZwepCE6X4KkG9FHjV\n" + + "WXyLgYFwCOcn+hkLhdpblms0wtjeSPITGOioSkefzhleJnDgJ9X4M3svd0HLTpJi\n" + + "lC1DmDZgdrXWITVdOoCogr2LFKNiGd0tbpKG533eKpfBALlm+afc6j73p1KhJEAn\n" + + "AfydDZqBRqv6+HHYplNDn/K2I1CZdkwaGrx3HOR/voGUi1sUI+hYbsPAFu8ZxrhD\n" + + "9UiysmLCfEUhqkbojony+L2mKsoLqyd24emQzn7GgMa7emlWX2jQUTwrD4SliZ2u\n" + + "OetVaZX5RLyqJWs4Igo/xye0xtMQN8INJ4hSZvnMQ1qFtuSRcQ==\n" + + "-----END CERTIFICATE-----"; + + // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, + // OU=0002 48146308100036, O=DHIMYOTIS, C=FR + // Issuer: CN=Certigna, O=Dhimyotis, C=FR + // Serial number: 6f82fa28acd6f784bb5b120ba87367ad + // Valid from: Wed Nov 25 03:33:52 PST 2015 until: Sat Nov 22 03:33:52 PST 2025 + private static final String INT_CERTIGNA = "-----BEGIN CERTIFICATE-----\n" + + "MIIGFjCCBP6gAwIBAgIQb4L6KKzW94S7WxILqHNnrTANBgkqhkiG9w0BAQsFADA0\n" + + "MQswCQYDVQQGEwJGUjESMBAGA1UECgwJRGhpbXlvdGlzMREwDwYDVQQDDAhDZXJ0\n" + + "aWduYTAeFw0xNTExMjUxMTMzNTJaFw0yNTExMjIxMTMzNTJaMH0xCzAJBgNVBAYT\n" + + "AkZSMRIwEAYDVQQKDAlESElNWU9USVMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgx\n" + + "MDAwMzYxHTAbBgNVBGEMFE5UUkZSLTQ4MTQ2MzA4MTAwMDM2MR0wGwYDVQQDDBRD\n" + + "ZXJ0aWduYSBTZXJ2aWNlcyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC\n" + + "ggIBALPM+7LpWBz9wFcPaTc3xnB+5g0XrnptB0EPPfrR04vO52Ykm4ky1d4ZLd10\n" + + "tbM1fa1RqNSOVWWg93O4pL7zCFKlz6JV74ZZVhHpEAwzBwv2oPnxvVbxtSN67xsS\n" + + "Y66ahUYxjzs8+3FhmsiRxqwnTYvK2u70uglUvRisOKyTL/M6JnrC4y8tlmoz7OSa\n" + + "5BmBMVplJFQtvmON6N9aHLvYMz+EyJPCbXL6pELxeHjFT5QmIaRamsr2DOTaCjtB\n" + + "ZKI1Wnh3X7lnbjM8MESJiV2t7E9tIQNG0Z/HI3tO4aaUMum3KysY5sC8v3vi7rry\n" + + "GidgzHQhrtP0ZXWW5UH/k7umLS/P/XXWnCFpc2Lxa1uDGfc2im7xibRoPP+JNZsz\n" + + "N76euFlls6jyEXAiwnVr14tVVTewLK0OWs5SJHpEKp8PGMZRDj59EmMvokWwzL6Q\n" + + "zNZ6vVAp00oOm05sbspNY9+MFqGKKUsKvhFGEa4XmRNxDe6KswLcjPZB+NKHZ0QW\n" + + "Fd4ip5C5XmEK/8qIPjwVr9dah9+oiHGGO8Wx7gJAMF5DTmkvW7GhqCKj1LmHnabj\n" + + "zc8av6kxWVQZi/C7HCm9i/W4wio+JA2EAFLqNL3GPNbK9kau4yPhQt/c7zxzo0OH\n" + + "nlsV4THCG7oOCd3cfCiyfQcb3FBt6OSpaKRZxjCLBwP00r0fAgMBAAGjggHZMIIB\n" + + "1TASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU\n" + + "rOyGj0s3HLh/FxsZ0K7oTuM0XBIwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF\n" + + "9lo53BGhOKQ2MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAP\n" + + "BgNVBAMMCENlcnRpZ25hggkA/tzjAQ/JSP8wSQYDVR0gBEIwQDA+BgoqgXoBgTEB\n" + + "AAECMDAwLgYIKwYBBQUHAgEWImh0dHBzOi8vd3d3LmNlcnRpZ25hLmZyL2F1dG9y\n" + + "aXRlcy8wfAYIKwYBBQUHAQEEcDBuMDQGCCsGAQUFBzAChihodHRwOi8vYXV0b3Jp\n" + + "dGUuY2VydGlnbmEuZnIvY2VydGlnbmEuZGVyMDYGCCsGAQUFBzAChipodHRwOi8v\n" + + "YXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5kZXIwYQYDVR0fBFowWDAp\n" + + "oCegJYYjaHR0cDovL2NybC5jZXJ0aWduYS5mci9jZXJ0aWduYS5jcmwwK6ApoCeG\n" + + "JWh0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9jZXJ0aWduYS5jcmwwDQYJKoZIhvcN\n" + + "AQELBQADggEBAGLft7gIuGPZVfg0cTM+HT2xAZFPDb/2+siH06x+dH044zMKbBIN\n" + + "bRzhKipwB1A3MW8FQjveE9tyrfyuqZE/X+o2SlGcdNV44ybYkxo4f6kcLEavV/IW\n" + + "+oFEnojZlhpksYcxrvQoEyqkAwshe8IS2KtZHKVACrt+XSs0lwvy7ALGmHaF7A4b\n" + + "y6cZWItA7Lhj8XWp+8tBJDj7HocRbWtxzEODdBuyMgJzFrNjc+97J0vH/K0+3yjm\n" + + "kczpKshMA0tM+MF9XDMN/MuwrPmUWGO/fHiqHgUp8yqeWtl1n44ZxkkK1t9GRwhn\n" + + "DWLv73/xhTmdhWYQ/reo0GbgBoLiltKmIJQ=\n" + + "-----END CERTIFICATE-----"; + + // Owner: SERIALNUMBER=S266241169, CN=valid.servicesca.dhimyotis.com, O=DHIMYOTIS, + // L=VILLENEUVE D'ASCQ, C=FR + // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, OU=0002 + // 48146308100036, O=DHIMYOTIS, C=FR + // Serial number: c641ef7b0340c21515d8c462e729dc0e + // Valid from: Thu Mar 09 15:00:00 PST 2023 until: Mon Mar 11 15:59:59 PDT 2024 + private static final String VALID = "-----BEGIN CERTIFICATE-----\n" + + "MIIIdzCCBl+gAwIBAgIRAMZB73sDQMIVFdjEYucp3A4wDQYJKoZIhvcNAQELBQAw\n" + + "fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw\n" + + "MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx\n" + + "HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIzMDMwOTIzMDAwMFoX\n" + + "DTI0MDMxMTIyNTk1OVowezELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + + "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxJzAlBgNVBAMMHnZhbGlkLnNl\n" + + "cnZpY2VzY2EuZGhpbXlvdGlzLmNvbTETMBEGA1UEBRMKUzI2NjI0MTE2OTCCASIw\n" + + "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJDrFpZWEeBJoMUuG37wEmJ7XVeX\n" + + "Jde1bgURpFbLwifRj2TVmMdtfg9hXHL7B7Mh/+I8/e7kJz8mlU9qUYKyH24oAitE\n" + + "myXYHAKTydqTseiM3mp92n4PM+DrgsdbT7bpmiirNM0/sqWFNyGUz7kP6Z5E3uuU\n" + + "HSlzX1LBBj8S0ORNZWvomQho11gjuZJRS72X4XTnSc0DESwnLp2irUfx7pflBNt0\n" + + "sLE8BhpNSSQd91naJVKtCtn0H7df+o4gGBt2ZceCLBwU0NwN8+KXz06KjP8298V4\n" + + "P3+eR2QxAw4QBIanRaG6Gd4AmpdIaT7TpiYHotjrJ/Pbx5C8/cmgxxlmtI0CAwEA\n" + + "AaOCA/IwggPuMIHkBggrBgEFBQcBAQSB1zCB1DA2BggrBgEFBQcwAoYqaHR0cDov\n" + + "L2F1dG9yaXRlLmNlcnRpZ25hLmZyL3NlcnZpY2VzY2EuZGVyMDgGCCsGAQUFBzAC\n" + + "hixodHRwOi8vYXV0b3JpdGUuZGhpbXlvdGlzLmNvbS9zZXJ2aWNlc2NhLmRlcjAu\n" + + "BggrBgEFBQcwAYYiaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5jZXJ0aWduYS5mcjAw\n" + + "BggrBgEFBQcwAYYkaHR0cDovL3NlcnZpY2VzY2Eub2NzcC5kaGlteW90aXMuY29t\n" + + "MB8GA1UdIwQYMBaAFKzsho9LNxy4fxcbGdCu6E7jNFwSMAkGA1UdEwQCMAAwYQYD\n" + + "VR0gBFowWDAIBgZngQwBAgIwTAYLKoF6AYExAgUBAQEwPTA7BggrBgEFBQcCARYv\n" + + "aHR0cHM6Ly93d3cuY2VydGlnbmEuY29tL2F1dG9yaXRlLWNlcnRpZmljYXRpb24w\n" + + "ZQYDVR0fBF4wXDAtoCugKYYnaHR0cDovL2NybC5kaGlteW90aXMuY29tL3NlcnZp\n" + + "Y2VzY2EuY3JsMCugKaAnhiVodHRwOi8vY3JsLmNlcnRpZ25hLmZyL3NlcnZpY2Vz\n" + + "Y2EuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA4GA1UdDwEB/wQEAwIFoDBIBgNV\n" + + "HREEQTA/gh12YWxpZC5zZXJ2aWNlc2NhLmNlcnRpZ25hLmNvbYIedmFsaWQuc2Vy\n" + + "dmljZXNjYS5kaGlteW90aXMuY29tMB0GA1UdDgQWBBSzyYZfPBt65RUDq98+e0AK\n" + + "U8pd/jCCAX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHcA7s3QZNXbGs7FXLedtM0T\n" + + "ojKHRny87N7DUUhZRnEftZsAAAGGy1ZNXwAABAMASDBGAiEAyG838/RfBOpojEI/\n" + + "cx++f0tvuDbc/rVa0WNcd2f9HekCIQDVKV2wI3VkD3wNmO93m022H7kvKD1OBEhw\n" + + "Tn6+0ZLA6QB2AHb/iD8KtvuVUcJhzPWHujS0pM27KdxoQgqf5mdMWjp0AAABhstW\n" + + "TcYAAAQDAEcwRQIhAOuj/r5G1wHNgFOMg3jsr3uWmWzIIkTmwmp4hJqvsJzzAiBf\n" + + "nm/jZCUW8DFY+iC+O/+Hzsk/kVDkKIlBDd6rA3MzJgB2AFWB1MIWkDYBSuoLm1c8\n" + + "U/DA5Dh4cCUIFy+jqh0HE9MMAAABhstWTw4AAAQDAEcwRQIgRbCAqI1/nxc6P4de\n" + + "Fqg/zc1+ldMDWjeamWjhctciGsgCIQDHQ4OKj0AA7hQKFIe1SVp+00BxRefFGmq7\n" + + "ZJ+8q+pRqzANBgkqhkiG9w0BAQsFAAOCAgEAVkzCC9LIHU+iOi+GFeCtWxxa5Fsk\n" + + "5gXnDJmtbdoVe2TJvOhrb+VnNI7/Ak+csBv3vxNl3P3DXIbPryB98aelleX7pkfP\n" + + "PcKhFAlbwzbII2D3L0mjFLERtVwdnoEJXXKcHsb9hJResKipZ//daMPD8FthHvEE\n" + + "HmtOrR0lHLjhbi4ODq0e4xyygbxFXXl5CCjtBw0jBtZaMDQaC3eemK9LkOggLz3h\n" + + "qs/+VQ7RyKfcKCuGC5Wb4GJR+IDKH812hFsUWmXe26MPoyTrzLNq6tfQZHSuY5Hj\n" + + "K0ZwldEkUZ2Hd7PrRlhCiGdVCp/2kS2yefhUkvX7Z5K5wX6n+LylfzOTvWf6ZPwQ\n" + + "1jTI0Js8ig4eHF25GlqgOWrqbyF9j67kLs3f7/c5Kx3FlclJ7/vlL8zEcTmGU7rm\n" + + "ZFOhEMDT/UYkitqAOvrgT60oIm9YJ1XTAVTeDbW0FFAb2nFmeBOrw8N3jaCb+jpO\n" + + "ysBA/lDaGTiQhMlJK44vwgS+TjbeWHxvmAE5srKa7MWU8Mmku2vuX95lupJo4LmD\n" + + "zOsihH00hyhtHFUB1TGXuaf77kFsipE6iycyxpcrpJ1UAWiZrba6PAZ85TbYhEdY\n" + + "FDNm7F7CVPU67HV5gE2kDa3Jprd1SjwO095LsRptWhzxUByhee3JI0jljBTaKowy\n" + + "jPv8oekm7zqCLzY=\n" + + "-----END CERTIFICATE-----"; + + // Owner: SERIALNUMBER=S266251168, CN=revoked.servicesca.certigna.com, O=DHIMYOTIS, + // L=VILLENEUVE D'ASCQ, C=FR + // Issuer: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, OU=0002 + // 48146308100036, O=DHIMYOTIS, C=FR + // Serial number: e863f752a23a735e3ccf958abf18565b + // Valid from: Thu Mar 09 15:00:00 PST 2023 until: Fri Mar 08 14:59:59 PST 2024 + private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" + + "MIIIezCCBmOgAwIBAgIRAOhj91KiOnNePM+Vir8YVlswDQYJKoZIhvcNAQELBQAw\n" + + "fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw\n" + + "MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx\n" + + "HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIzMDMwOTIzMDAwMFoX\n" + + "DTI0MDMwODIyNTk1OVowfDELMAkGA1UEBhMCRlIxGjAYBgNVBAcMEVZJTExFTkVV\n" + + "VkUgRCdBU0NRMRIwEAYDVQQKDAlESElNWU9USVMxKDAmBgNVBAMMH3Jldm9rZWQu\n" + + "c2VydmljZXNjYS5jZXJ0aWduYS5jb20xEzARBgNVBAUTClMyNjYyNTExNjgwggEi\n" + + "MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCBqKNjMkHqJ9EQa3CjuZ6EYMz6\n" + + "mWODrEucRcJDihYMigaV1oRyquGlFQ82ootXaK5bU+EYSMmUwbRpdZ9G/oZUn2+K\n" + + "MKAFDI+MoZoFhQC+2w0AzJycCf/hShUVxcRREKRKdfzv+k5YHj3e8ic16tGlTFXT\n" + + "IF1x3y2Uru7mzZARsZJqnRqaqPPghT/QlBpcA04yLi3iSpgO++mRrJxTUoUHlDw/\n" + + "a1nhqnDgH2yKN7tSfwFTetnXat6/UVt0CJ/6dJF6oY8bGWO1YB03Xdq735eLdJE4\n" + + "t38pV/X8rf5Mc9ZQh8IGrjVW83M8mQmqaX5rbsOl0ZCA/q6RWxRFEF2SwK+dAgMB\n" + + "AAGjggP1MIID8TCB5AYIKwYBBQUHAQEEgdcwgdQwNgYIKwYBBQUHMAKGKmh0dHA6\n" + + "Ly9hdXRvcml0ZS5jZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmRlcjA4BggrBgEFBQcw\n" + + "AoYsaHR0cDovL2F1dG9yaXRlLmRoaW15b3Rpcy5jb20vc2VydmljZXNjYS5kZXIw\n" + + "LgYIKwYBBQUHMAGGImh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuY2VydGlnbmEuZnIw\n" + + "MAYIKwYBBQUHMAGGJGh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuZGhpbXlvdGlzLmNv\n" + + "bTAfBgNVHSMEGDAWgBSs7IaPSzccuH8XGxnQruhO4zRcEjAJBgNVHRMEAjAAMGEG\n" + + "A1UdIARaMFgwCAYGZ4EMAQICMEwGCyqBegGBMQIFAQEBMD0wOwYIKwYBBQUHAgEW\n" + + "L2h0dHBzOi8vd3d3LmNlcnRpZ25hLmNvbS9hdXRvcml0ZS1jZXJ0aWZpY2F0aW9u\n" + + "MGUGA1UdHwReMFwwLaAroCmGJ2h0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9zZXJ2\n" + + "aWNlc2NhLmNybDAroCmgJ4YlaHR0cDovL2NybC5jZXJ0aWduYS5mci9zZXJ2aWNl\n" + + "c2NhLmNybDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBaAwTAYD\n" + + "VR0RBEUwQ4IgcmV2b2tlZC5zZXJ2aWNlc2NhLmRoaW15b3Rpcy5jb22CH3Jldm9r\n" + + "ZWQuc2VydmljZXNjYS5jZXJ0aWduYS5jb20wHQYDVR0OBBYEFEQsKyX8x8zVxVC2\n" + + "HEK7+bOBLoMkMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgDuzdBk1dsazsVc\n" + + "t520zROiModGfLzs3sNRSFlGcR+1mwAAAYbLTxPnAAAEAwBHMEUCIQD16IHX+8+4\n" + + "zWnxIME4rzCgQIA4m5OsEqP6ssgRG5iurwIgdBOGFGlF6+DGPSm5FKuk5ShAA8ZC\n" + + "AE+E27CKLkBTnfgAdgB2/4g/Crb7lVHCYcz1h7o0tKTNuyncaEIKn+ZnTFo6dAAA\n" + + "AYbLTxRMAAAEAwBHMEUCIDmW9elysDm3zAeIXsgJwmL33EoMTyVhA3ah2jkvMjzv\n" + + "AiEA6aIZXtwk2DnFt+GA6gLr4UgswUCuK4wxheDVwbpSw/4AdgA7U3d1Pi25gE6L\n" + + "MFsG/kA7Z9hPw/THvQANLXJv4frUFwAAAYbLTxXAAAAEAwBHMEUCIQDGuOg7koEE\n" + + "H9K4VkSHaDD9rAndys2BtswdspfRKUFR3QIgVZ7QUX3H56ECuI8wsAkSjBze4lBO\n" + + "RgfN2xh3l9xQOK0wDQYJKoZIhvcNAQELBQADggIBAFQTTtyQSoV4Zq3QYMnb0yEp\n" + + "u6Hwic/wpYN5L0km+zZoHWuf58vfj8Yg/sfKmftGSZHDdc3NfYSVBlT/0Hl4SDhi\n" + + "zHLLyapoX2GNhbg3esu0Y1fch8E16z2A/wAwrFvxI0XrjHpOyDp4CBDYqDADNPiL\n" + + "vlEkiwP6r7WHjUdWRb7W0t75uAkcajn46XKpFmaHHie5KBch+KDGsUionuH5ZW8Y\n" + + "klh2B34uLWcGZuIR7PeCO9+91mbn/bBNeabGC70qMStaB139lp9P2M+l2WpyREUK\n" + + "l7qHwTsrlMmNb8n44zGtY4wL9NSYWTdTfhcU0FAPdPcLlnjoQubJ1O0vPkzfVYns\n" + + "WQrslxoCBor6CL6AYMQz3jbzQ0soD3Reb11+uTngWGJZtx4DT09RFB3a+1rcYjiS\n" + + "ijCBB+Lqx0xfLQnfBv1A0wjNqUY+gyEe0SpXqB4edqy5uaqawRRKMuNSnb2BVz0/\n" + + "keo1Kif/GSak+JUBpJ8hkJWygtrWCETUNfoseQhqo3gism0EGxJ04tBp+DRvfbrz\n" + + "X4aBgALRro3jSIR1Ibp+e0fxePwShy715SF2H4SfjvplTAKq5bwztZtQUkPR6fJ7\n" + + "5xT0f762c1yytKP1rHFMvzl6k7QWvC6zb2FeG5UqXJw3wFxxWsCuAUu5SPFfXdno\n" + + "5lIHTTV5rpZBN+PzTZsz\n" + + "-----END CERTIFICATE-----"; + + public static void main(String[] args) throws Exception { + // OCSP check by default + boolean ocspEnabled = args.length < 1 || !"CRL".equalsIgnoreCase(args[0]); + + // CN=Certigna + new CertignaCAs().runTest(ocspEnabled, + VALID, + REVOKED, + INT_CERTIGNA); + + // CN=Certigna Root CA + new CertignaCAs().runTest(ocspEnabled, + VALID, + REVOKED, + INT_CERTIGNA_ROOT_CA); + } +} + +class CertignaCAs { + public void runTest(boolean ocspEnabled, + final String VALID, + final String REVOKED, + final String INT_CERT) throws Exception { + + ValidatePathWithParams pathValidator; + String[] validChainToValidate; + String[] revChainToValidate; + + if (!ocspEnabled) { + pathValidator = new ValidatePathWithParams(null); + pathValidator.enableCRLCheck(); + + validChainToValidate = new String[]{VALID, INT_CERT}; + revChainToValidate = new String[]{REVOKED, INT_CERT}; + } else { + // int certificate doesn't specify OCSP responder + pathValidator = new ValidatePathWithParams(new String[]{INT_CERT}); + pathValidator.enableOCSPCheck(); + + validChainToValidate = new String[]{VALID}; + revChainToValidate = new String[]{REVOKED}; + } + + // Validate valid + pathValidator.validate(validChainToValidate, + ValidatePathWithParams.Status.GOOD, null, System.out); + + // Validate Revoked + pathValidator.validate(revChainToValidate, + ValidatePathWithParams.Status.REVOKED, + "Fri Mar 10 03:39:51 PST 2023", System.out); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/java2d/loops/SkipConversionIfPossible.java openjdk-lts-11.0.21+9/test/jdk/sun/java2d/loops/SkipConversionIfPossible.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/java2d/loops/SkipConversionIfPossible.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/java2d/loops/SkipConversionIfPossible.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,89 @@ +/* + * 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.AlphaComposite; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.util.Arrays; + +import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR; +import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR; +import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE; +import static java.awt.image.BufferedImage.TYPE_INT_ARGB; +import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE; +import static java.awt.image.BufferedImage.TYPE_INT_BGR; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; + +/** + * @test + * @bug 8297681 + * @summary The blit TYPE_4BYTE_ABGR_PRE to TYPE_INT_ARGB_PRE should be "direct" + */ +public final class SkipConversionIfPossible { + + private static final int SIZE = 256; + + public static void main(String[] args) { + // Initial bug was in the TYPE_4BYTE_ABGR_PRE to TYPE_INT_ARGB_PRE blit. + // But I checked other blits just in case. + test(new int[]{TYPE_INT_ARGB_PRE, TYPE_4BYTE_ABGR_PRE}); + test(new int[]{TYPE_INT_RGB, TYPE_INT_BGR, TYPE_3BYTE_BGR}); + test(new int[]{TYPE_INT_ARGB, TYPE_4BYTE_ABGR}); + } + + private static void test(int[] types) { + for (int src : types) { + for (int dst : types) { + render(src, dst); + } + } + } + + private static void render(int src, int dst) { + BufferedImage from = new BufferedImage(SIZE, SIZE, src); + for (int a = 0; a < SIZE; ++a) { + for (int c = 0; c < SIZE; ++c) { + // The data is intentionally broken for the argb_pre format, but + // it should be stored as is in dst if no conversion was done. + from.getRaster().setPixel(c, a, new int[]{c, c << 24, -c, a}); + } + } + BufferedImage to = new BufferedImage(SIZE, SIZE, dst); + Graphics2D g = to.createGraphics(); + g.setComposite(AlphaComposite.Src); + g.drawImage(from, 0, 0, null); + g.dispose(); + + for (int a = 0; a < SIZE; ++a) { + for (int c = 0; c < SIZE; ++c) { + int[] pixel1 = from.getRaster().getPixel(c, a, (int[]) null); + int[] pixel2 = to.getRaster().getPixel(c, a, (int[]) null); + if (!Arrays.equals(pixel1, pixel2)) { + System.err.println(Arrays.toString(pixel1)); + System.err.println(Arrays.toString(pixel2)); + throw new RuntimeException(); + } + } + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in openjdk-lts-11.0.21+9/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in --- openjdk-lts-11.0.20.1+1/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/management/jmxremote/bootstrap/management_ssltest07_ok.properties.in 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ -com.sun.management.jmxremote.ssl.enabled.cipher.suites=TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 +com.sun.management.jmxremote.ssl.enabled.cipher.suites=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA com.sun.management.jmxremote.ssl.enabled.protocols=SSLv2Hello,SSLv3,TLSv1 com.sun.management.jmxremote.ssl.need.client.auth=true com.sun.management.jmxremote.authenticate=false -javax.rmi.ssl.client.enabledCipherSuites=TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 +javax.rmi.ssl.client.enabledCipherSuites=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/ftp/B6427768.java openjdk-lts-11.0.21+9/test/jdk/sun/net/ftp/B6427768.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/ftp/B6427768.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/ftp/B6427768.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -105,13 +105,14 @@ } public static void main(String[] args) throws IOException { - FtpServer server = new FtpServer(0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + FtpServer server = new FtpServer(loopback, 0); int port = server.getLocalPort(); server.setFileSystemHandler(new MyFileSystemHandler("/")); server.setAuthHandler(new MyAuthHandler()); server.start(); - URL url = new URL("ftp://user:passwd@localhost:" + port + "/foo.txt"); - URLConnection con = url.openConnection(); + URL url = new URL("ftp://user:passwd@" + server.getAuthority() + "/foo.txt"); + URLConnection con = url.openConnection(Proxy.NO_PROXY); // triggers the connection try { con.getInputStream(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/ftp/FtpURLConnectionLeak.java openjdk-lts-11.0.21+9/test/jdk/sun/net/ftp/FtpURLConnectionLeak.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/ftp/FtpURLConnectionLeak.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/ftp/FtpURLConnectionLeak.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -32,17 +32,19 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.io.OutputStream; +import java.net.InetAddress; import java.net.URL; public class FtpURLConnectionLeak { public static void main(String[] args) throws Exception { - FtpServer server = new FtpServer(0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + FtpServer server = new FtpServer(loopback, 0); server.setFileSystemHandler(new CustomFileSystemHandler("/")); server.setAuthHandler(new MyAuthHandler()); - int port = server.getLocalPort(); + String authority = server.getAuthority(); server.start(); - URL url = new URL("ftp://localhost:" + port + "/filedoesNotExist.txt"); + URL url = new URL("ftp://" + authority + "/filedoesNotExist.txt"); try (server) { for (int i = 0; i < 3; i++) { try { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/AuthHeaderTest.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/AuthHeaderTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/AuthHeaderTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/AuthHeaderTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -96,10 +96,11 @@ public static void main (String[] args) throws Exception { MyAuthenticator auth = new MyAuthenticator (); Authenticator.setDefault (auth); + InetAddress loopback = InetAddress.getLoopbackAddress(); try { - server = new TestHttpServer (new AuthHeaderTest(), 1, 10, 0); - System.out.println ("Server: listening on port: " + server.getLocalPort()); - client ("http://localhost:"+server.getLocalPort()+"/d1/foo.html"); + server = new TestHttpServer (new AuthHeaderTest(), 1, 10, loopback, 0); + System.out.println ("Server: listening on port: " + server.getAuthority()); + client ("http://" + server.getAuthority() + "/d1/foo.html"); } catch (Exception e) { if (server != null) { server.terminate(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/ftptest/FtpCommandHandler.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/ftptest/FtpCommandHandler.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/ftptest/FtpCommandHandler.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/ftptest/FtpCommandHandler.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -238,14 +238,14 @@ return; } try { - if (pasv == null) - pasv = new ServerSocket(0); - int port = pasv.getLocalPort(); InetAddress rAddress = cmd.getLocalAddress(); if (rAddress instanceof Inet6Address) { out.println("500 PASV illegal over IPv6 addresses, use EPSV."); return; } + if (pasv == null) + pasv = new ServerSocket(0, 0, rAddress); + int port = pasv.getLocalPort(); byte[] a = rAddress.getAddress(); out.println("227 Entering Passive Mode " + a[0] + "," + a[1] + "," + a[2] + "," + a[3] + "," + (port >> 8) + "," + (port & 0xff) ); @@ -266,7 +266,7 @@ } try { if (pasv == null) - pasv = new ServerSocket(0); + pasv = new ServerSocket(0, 0, parent.getInetAddress()); int port = pasv.getLocalPort(); out.println("229 Entering Extended Passive Mode (|||" + port + "|)"); } catch (IOException e) { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/ftptest/FtpServer.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/ftptest/FtpServer.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/ftptest/FtpServer.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/ftptest/FtpServer.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -59,6 +59,16 @@ * connections on the specified port. If the port is set to 0, it will * automatically select an available ephemeral port. */ + public FtpServer(InetAddress addr, int port) throws IOException { + listener = new ServerSocket(); + listener.bind(new InetSocketAddress(addr, port)); + } + + /** + * Creates an instance of an FTP server which will listen for incoming + * connections on the specified port. If the port is set to 0, it will + * automatically select an available ephemeral port. + */ public FtpServer(int port) throws IOException { listener = new ServerSocket(port); } @@ -100,6 +110,21 @@ return listener.getLocalPort(); } + public InetAddress getInetAddress() { + return listener.getInetAddress(); + } + + public String getAuthority() { + InetAddress address = getInetAddress(); + String hostaddr = address.isAnyLocalAddress() + ? "localhost" : address.getHostAddress(); + if (hostaddr.indexOf(':') > -1) { + hostaddr = "[" + hostaddr + "]"; + } + return hostaddr + ":" + getLocalPort(); + } + + void addClient(Socket client) { FtpCommandHandler h = new FtpCommandHandler(client, this); h.setHandlers(fsh, auth); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,7 @@ * @test * @bug 4333920 * @modules jdk.httpserver + * @library /test/lib * @run main ChunkedEncodingTest * @summary ChunkedEncodingTest unit test */ @@ -36,6 +37,7 @@ import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpExchange; import static java.lang.System.out; +import jdk.test.lib.net.URIBuilder; public class ChunkedEncodingTest{ private static MessageDigest serverDigest, clientDigest; @@ -61,7 +63,13 @@ int port = server.getAddress().getPort(); out.println ("Server listening on port: " + port); - client("http://localhost:" + port + "/chunked/"); + String url = URIBuilder.newBuilder() + .scheme("http") + .host(server.getAddress().getAddress()) + .port(port) + .path("/chunked/") + .build().toString(); + client(url); if (!MessageDigest.isEqual(clientMac, serverMac)) { throw new RuntimeException( @@ -83,7 +91,8 @@ * Http Server */ static HttpServer startHttpServer() throws IOException { - HttpServer httpServer = HttpServer.create(new InetSocketAddress(0), 0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + HttpServer httpServer = HttpServer.create(new InetSocketAddress(loopback, 0), 0); HttpHandler httpHandler = new SimpleHandler(); httpServer.createContext("/chunked/", httpHandler); httpServer.start(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/ChunkedInputStream/ChunkedEncodingWithProgressMonitorTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -27,6 +27,7 @@ * @summary ChunkedEncoding unit test; MeteredStream/ProgressData problem * @modules java.base/sun.net * jdk.httpserver + * @library /test/lib * @run main ChunkedEncodingWithProgressMonitorTest */ diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/ChunkedInputStream/TestAvailable.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/ChunkedInputStream/TestAvailable.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/ChunkedInputStream/TestAvailable.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/ChunkedInputStream/TestAvailable.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,6 +25,7 @@ * @test * @bug 6446990 * @modules jdk.httpserver + * @library /test/lib * @run main/othervm TestAvailable * @summary HttpURLConnection#available() reads more and more data into memory */ @@ -35,6 +36,7 @@ import com.sun.net.httpserver.*; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; +import jdk.test.lib.net.URIBuilder; public class TestAvailable { @@ -60,7 +62,13 @@ try { InetSocketAddress address = httpServer.getAddress(); - URL url = new URL("http://localhost:" + address.getPort() + "/testAvailable/"); + URL url = URIBuilder.newBuilder() + .scheme("http") + .host(address.getAddress()) + .port(address.getPort()) + .path("/testAvailable/") + .toURLUnchecked(); + HttpURLConnection uc = (HttpURLConnection)url.openConnection(); uc.setDoOutput(true); @@ -102,7 +110,9 @@ * Http Server */ public void startHttpServer() throws IOException { - httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + InetSocketAddress sockaddr = new InetSocketAddress(loopback, 0); + httpServer = com.sun.net.httpserver.HttpServer.create(sockaddr, 0); // create HttpServer context HttpContext ctx = httpServer.createContext("/testAvailable/", new MyHandler()); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/HttpClient/MultiThreadTest.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/HttpClient/MultiThreadTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/HttpClient/MultiThreadTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/HttpClient/MultiThreadTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, 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 @@ -25,6 +25,7 @@ * @test * @bug 4636628 * @summary HttpURLConnection duplicates HTTP GET requests when used with multiple threads + * @run main MultiThreadTest */ /* @@ -40,9 +41,14 @@ import java.net.*; import java.io.*; import java.time.Duration; +import java.util.ArrayList; +import java.util.List; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; public class MultiThreadTest extends Thread { @@ -51,8 +57,13 @@ */ static boolean debug = true; // disable debug once stability proven - static Object threadlock = new Object (); + static final Object threadlock = new Object (); static int threadCounter = 0; + // KEEP_ALIVE sent by the server + static final int KEEP_ALIVE = 1; // seconds + // The sending thread will sleep for this time after sending + // half the number of its requests + static final int SLEEP = KEEP_ALIVE * 1000 + 500; // ms static Object getLock() { return threadlock; } @@ -63,6 +74,9 @@ static final AtomicInteger reqnum = new AtomicInteger(); + // Set to true after all requests have been sent + static final AtomicBoolean DONE = new AtomicBoolean(); + void doRequest(String uri) throws Exception { URL url = new URL(uri + "?foo="+reqnum.getAndIncrement()); HttpURLConnection http = (HttpURLConnection)url.openConnection(); @@ -79,42 +93,49 @@ http.disconnect(); } - String uri; - byte[] b; - int requests; - - MultiThreadTest(int port, int requests) throws Exception { - uri = "http://localhost:" + port + "/foo.html"; - + final String uri; + final byte[] b; + final int requests; + final CountDownLatch countDown; + + MultiThreadTest(String authority, int requests, CountDownLatch latch) throws Exception { + countDown = latch; + uri = "http://" + authority + "/foo.html"; b = new byte [256]; this.requests = requests; - - synchronized (threadlock) { - threadCounter ++; - } } public void run() { long start = System.nanoTime(); - try { for (int i=0; i tests = new ArrayList<>(); + for (int i = 0; i < threads; i++) { + MultiThreadTest t = new MultiThreadTest(svr.getAuthority(), requests, latch); + tests.add(t); + t.start(); } - try { - lock.wait(); - } catch (InterruptedException e) {} - } - - // shutdown server - we're done. - svr.shutdown(); - - int cnt = svr.connectionCount(); - MultiThreadTest.debug("Connections = " + cnt); - int reqs = Worker.getRequests (); - MultiThreadTest.debug("Requests = " + reqs); - System.out.println ("Connection count = " + cnt + " Request count = " + reqs); - // We may have received traffic from something else than - // our client. We should only count those workers for which - // the expected header has been found. - int validConnections = 0; - for (Worker w : svr.workers()) { - if (w.headerFound) validConnections++; - } + latch.await(); + long end = System.nanoTime(); + DONE.compareAndSet(false, true); + for (var test : tests) test.join(); + + MultiThreadTest.debug("DONE at " + at(end) + "ms"); + + // shutdown server - we're done. + svr.shutdown(); + + int cnt = svr.connectionCount(); + MultiThreadTest.debug("Connections = " + cnt); + int reqs = Worker.getRequests(); + MultiThreadTest.debug("Requests = " + reqs); + System.out.println("Connection count = " + cnt + " Request count = " + reqs); + + // We may have received traffic from something else than + // our client. We should only count those workers for which + // the expected header has been found. + int validConnections = 0; + // We detect worker threads that may have timed out, so we don't include them in + // the count to compare with the number of connections. + int becameIdle = 0; + for (Worker w : svr.workers()) { + if (w.headerFound > 0) { + validConnections++; + if (w.mayHaveTimedOut(end)) { + debug("Worker " + w.id + " may have timed out"); + becameIdle++; + } else { + long at0 = at(w.lastReading); + long at1 = at(w.lastReplied); + debug("Worker " + w.id +" has not timed out - last used at " + + Math.max(at0, at1)); + } + } else { + debug("Worker " + w.id + " is not a valid connection"); + } + } - if (validConnections > threads + 1 || validConnections == 0) { // could be less - throw new RuntimeException ("Expected " + threads + " connections: used " + validConnections); - } + if (validConnections > threads) { + if (SLEEP > KEEP_ALIVE) { + debug("INFO: " + validConnections + + " have been used, with " + becameIdle + + " becoming idle for more than " + KEEP_ALIVE + "s" + + " while using " + threads + + " threads to make concurrent connections"); + } else { + debug("WARNING: " + validConnections + + " have been used, with " + becameIdle + + " becoming idle for more than " + KEEP_ALIVE + "s" + + " where only " + threads + + " connections and none idle were expected!"); + } + } - // Sometimes the client drops a connection after a while and - // spawns a new one. Why this is happening is not clear, - // and JDK-8223783 is logged to follow up on this. For the sake - // of test stabilization we don't fail on `threads + 1` connections - // but log a warning instead. - if (validConnections == threads + 1) { - debug("WARNING: " + validConnections - + " have been used, where only " + threads - + " were expected!"); - } + if (validConnections > threads + becameIdle || validConnections == 0) { // could be less + throw new RuntimeException("Expected " + (threads + becameIdle) + " connections: used " + validConnections); + } - if (validConnections != cnt) { - debug("WARNING: got " + (cnt - validConnections) + " unexpected connections!"); - } - if (validConnections == cnt && reqs != threads*requests) { - throw new RuntimeException ("Expected "+ threads*requests+ " requests: got " +reqs); - } + if (validConnections != cnt) { + debug("INFO: got " + (cnt - validConnections) + " unexpected connections"); + } + if (reqs != threads * requests) { + throw new RuntimeException("Expected " + threads * requests + " requests: got " + reqs); + } - for (Thread worker : svr.workers()) { - worker.join(60_000); + } finally { + debug("waiting for worker to shutdown at " + at() +"ms"); + for (Worker worker : svr.workers()) { + // We want to verify that the client will eventually + // close the idle connections. So just join the worker + // and wait... This shouldn't take more than the granularity + // of the keep-alive cache timer - so we're not actually + // going to have to wait for one full minute here. + worker.join(60_000); + } } - debug("main thread end - " + Duration.ofNanos(System.nanoTime() - start)); + debug("main thread end - " + at() + "ms"); } } @@ -209,6 +268,16 @@ this.ss = ss; } + public String getAuthority() { + InetAddress address = ss.getInetAddress(); + String hostaddr = address.isAnyLocalAddress() + ? "localhost" : address.getHostAddress(); + if (hostaddr.indexOf(':') > -1) { + hostaddr = "[" + hostaddr + "]"; + } + return hostaddr + ":" + ss.getLocalPort(); + } + public Queue workers() { return workers; } @@ -219,34 +288,45 @@ public synchronized void shutdown() { shutdown = true; + try { + ss.close(); + } catch (IOException x) { + } } public void run() { try { - ss.setSoTimeout(2000); + ss.setSoTimeout(6000); + long startServer = System.nanoTime(); for (;;) { Socket s; + long acceptTime; try { MultiThreadTest.debug("server: calling accept."); s = ss.accept(); - MultiThreadTest.debug("server: return accept."); - } catch (SocketTimeoutException te) { + acceptTime = System.nanoTime(); + MultiThreadTest.debug("server: return accept (at " + + MultiThreadTest.at(acceptTime)+ "ms)"); + } catch (IOException te) { MultiThreadTest.debug("server: STE"); synchronized (this) { if (shutdown) { - MultiThreadTest.debug("server: Shuting down."); + MultiThreadTest.debug("server: Shuting down at: " + + MultiThreadTest.at() + "ms"); return; } } - continue; + if (te instanceof SocketTimeoutException) + continue; + throw te; } int id; Worker w; synchronized (this) { id = connectionCount++; - w = new Worker(s, id); + w = new Worker(s, id, acceptTime); workers.add(w); } w.start(); @@ -268,14 +348,39 @@ * multiple http requests on same connection. */ class Worker extends Thread { - Socket s; - int id; - volatile boolean headerFound; + final long TIMEOUT = MultiThreadTest.KEEP_ALIVE; // seconds + final long KEEP_ALIVE_NS = Duration.ofSeconds(TIMEOUT).toNanos(); // nanos + final Socket s; + final int id; + + // time at which the connection was accepted (nanos) + final long acceptTime; + + // number of requests that had the expected URI + volatile int headerFound; + // time at which the worker thread exited + volatile long stopTime; + // Time at which the first call to is.read() for the last request + // returned. This includes cases where -1 was returned. + volatile long startReading; + // Lat time at which a byte was read from the stream. + volatile long lastReading; + // number of times that the time between two consecutive received requests + // exceeded the KEEP_ALIVE timeout. + volatile int timeoutExceeded; + // Number of requests handled by this worker + volatile int requestHandled; + // Time at which the last byte of the last reply was sent + volatile long lastReplied; + // Whether the worker was asked to stop + volatile boolean done; - Worker(Socket s, int id) { + Worker(Socket s, int id, long acceptTime) { super("Worker-" + id); this.s = s; this.id = id; + // no time can have a value before accepTime + this.acceptTime = lastReading = lastReplied = startReading = acceptTime; } static int requests = 0; @@ -293,12 +398,42 @@ } } + /** + * {@return Whether this worker might have been idle for more + * than the KEEP_ALIVE timeout} + * This will be true if the worker detected that the idle timeout + * was exceeded between two consecutive request, or + * if the time between the last reply and `nanosNow` exceeds + * the keep-alive time. + * @param nanosNow a timestamp in nano seconds + */ + public boolean mayHaveTimedOut(long nanosNow) { + // the minimum time elapsed between nanosNow and: + // - the time the socket was accepted + // - the last time a byte was received + // - the last time a reply was sent. + // We must not use `startReading` here because `startReading` may + // be set if the client asynchronously closes the connection + // after all requests have been sent. We should really only + // take into account `lastReading` and `lastReplied`. + long idle = Math.min(nanosNow - lastReading, nanosNow - lastReplied); + return timeoutExceeded > 0 || idle >= KEEP_ALIVE_NS; + } + int readUntil(InputStream in, StringBuilder headers, char[] seq) throws IOException { int i=0, count=0; + long last; while (true) { int c = in.read(); + last = System.nanoTime(); + if (count == 0) { + // time at which the first byte of the request (or EOF) was received + startReading = last; + } if (c == -1) return -1; + // time at which the last byte of the request was received (excludes EOF) + lastReading = last; headers.append((char)c); count++; if (c == seq[i]) { @@ -315,6 +450,9 @@ public void run() { long start = System.nanoTime(); + // lastUsed starts when the connection was accepted + long lastUsed = acceptTime; + int expectedReqs = 0; try { int max = 400; byte b[] = new byte[1000]; @@ -325,38 +463,49 @@ s.getOutputStream() )); for (;;) { - // read entire request from client - int n=0; + int n; StringBuilder headers = new StringBuilder(); n = readUntil(in, headers, new char[] {'\r','\n', '\r','\n'}); + long idle = startReading - lastUsed; + if (idle >= KEEP_ALIVE_NS) { + if (!MultiThreadTest.DONE.get()) { + // avoid increasing timeoutExceeded after the test is no + // longer sending requests. + timeoutExceeded++; + } + } if (n <= 0) { - MultiThreadTest.debug("worker: " + id + ": Shutdown"); + MultiThreadTest.debug("worker: " + id + ": Shutdown at " + + MultiThreadTest.at() + "ms"); s.close(); return; } if (headers.toString().contains("/foo.html?foo=")) { - headerFound = true; + headerFound = ++expectedReqs; + incRequests(); } else { MultiThreadTest.debug("worker: " + id + ": Unexpected request received: " + headers); + s.close(); + return; } MultiThreadTest.debug("worker " + id + ": Read request from client " + - "(" + n + " bytes)."); + "(" + n + " bytes) at " + MultiThreadTest.at() + "ms"); - incRequests(); out.print("HTTP/1.1 200 OK\r\n"); out.print("Transfer-Encoding: chunked\r\n"); out.print("Content-Type: text/html\r\n"); out.print("Connection: Keep-Alive\r\n"); - out.print("Keep-Alive: timeout=15, max="+max+"\r\n"); + out.print("Keep-Alive: timeout=" + TIMEOUT + ", max="+max+"\r\n"); out.print("\r\n"); out.print("6\r\nHello \r\n"); out.print("5\r\nWorld\r\n"); out.print("0\r\n\r\n"); out.flush(); - + requestHandled++; + lastUsed = lastReplied = System.nanoTime(); if (--max == 0) { s.close(); return; @@ -366,11 +515,19 @@ } catch (Exception e) { e.printStackTrace(); } finally { + long end = stopTime = System.nanoTime(); try { s.close(); } catch (Exception e) { } - MultiThreadTest.debug("worker: " + id + " end - " + - Duration.ofNanos(System.nanoTime() - start)); + MultiThreadTest.debug("worker: " + id + " end at " + + MultiThreadTest.at() + "ms, elapsed since worker start: " + + Duration.ofNanos(end - start).toMillis() + "ms, elapsed since accept: " + + Duration.ofNanos(end - acceptTime).toMillis() + + "ms, timeout exceeded: " + timeoutExceeded + + ", successfuly handled " + requestHandled + "/" + + expectedReqs + " genuine requests, " + + ", mayHaveTimedOut: " + mayHaveTimedOut(end)); } } + } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/HttpClient/RetryPost.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/HttpClient/RetryPost.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/HttpClient/RetryPost.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/HttpClient/RetryPost.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -25,6 +25,7 @@ * @test * @bug 6427251 6382788 * @modules jdk.httpserver + * @library /test/lib * @run main RetryPost * @run main/othervm -Dsun.net.http.retryPost=false RetryPost noRetry * @summary HttpURLConnection automatically retries non-idempotent method POST @@ -36,12 +37,14 @@ import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.SocketException; import java.net.URL; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; +import jdk.test.lib.net.URIBuilder; public class RetryPost { @@ -66,7 +69,12 @@ void doClient() throws Exception { try { InetSocketAddress address = httpServer.getAddress(); - URL url = new URL("http://localhost:" + address.getPort() + "/test/"); + URL url = URIBuilder.newBuilder() + .scheme("http") + .host(address.getAddress()) + .port(address.getPort()) + .path("/test/") + .toURLUnchecked(); HttpURLConnection uc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY); uc.setDoOutput(true); uc.setRequestMethod("POST"); @@ -93,7 +101,8 @@ * Http Server */ public void startHttpServer(boolean shouldRetry) throws IOException { - httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(loopback, 0), 0); httpHandler = new MyHandler(shouldRetry); HttpContext ctx = httpServer.createContext("/test/", httpHandler); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/HttpURLConnection/DigestAuth.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/HttpURLConnection/DigestAuth.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/HttpURLConnection/DigestAuth.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/HttpURLConnection/DigestAuth.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.Authenticator; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.URL; @@ -54,7 +55,6 @@ */ public class DigestAuth { - static final String LOCALHOST = "localhost"; static final String EXPECT_FAILURE = null; static final String EXPECT_DIGEST = "Digest"; static final String REALM = "testrealm@host.com"; @@ -119,8 +119,7 @@ AuthenticatorImpl auth = new AuthenticatorImpl(); Authenticator.setDefault(auth); - String url = String.format("http://%s:%d/test/", - LOCALHOST, server.getPort()); + String url = String.format("http://%s/test/", server.getAuthority()); boolean success = true; switch (testcase) { @@ -322,6 +321,16 @@ this.server = server; } + public String getAuthority() { + InetAddress address = server.getAddress().getAddress(); + String hostaddr = address.isAnyLocalAddress() + ? "localhost" : address.getHostAddress(); + if (hostaddr.indexOf(':') > -1) { + hostaddr = "[" + hostaddr + "]"; + } + return hostaddr + ":" + getPort(); + } + void setWWWAuthHeader(String wwwAuthHeader) { this.wwwAuthHeader = wwwAuthHeader; } @@ -331,8 +340,9 @@ } static LocalHttpServer startServer() throws IOException { + InetAddress loopback = InetAddress.getLoopbackAddress(); HttpServer httpServer = HttpServer.create( - new InetSocketAddress(0), 0); + new InetSocketAddress(loopback, 0), 0); LocalHttpServer localHttpServer = new LocalHttpServer(httpServer); localHttpServer.start(); @@ -342,7 +352,7 @@ void start() { server.createContext("/test", this); server.start(); - System.out.println("HttpServer: started on port " + getPort()); + System.out.println("HttpServer: started on port " + getAuthority()); } void stop() { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/KeepAliveCache/B8293562.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/KeepAliveCache/B8293562.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/http/KeepAliveCache/B8293562.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/http/KeepAliveCache/B8293562.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,238 @@ +/* + * 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 8293562 + * @library /test/lib + * @run main/othervm -Dhttp.keepAlive.time.server=1 B8293562 + * @summary Http keep-alive thread should close sockets without holding a lock + */ + +import com.sun.net.httpserver.HttpServer; + +import javax.net.ssl.HandshakeCompletedListener; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.Socket; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class B8293562 { + static HttpServer server; + static CountDownLatch closing = new CountDownLatch(1); + static CountDownLatch secondRequestDone = new CountDownLatch(1); + static CompletableFuture result = new CompletableFuture<>(); + + public static void main(String[] args) throws Exception { + startHttpServer(); + clientHttpCalls(); + } + + public static void startHttpServer() throws Exception { + server = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 10); + server.setExecutor(Executors.newCachedThreadPool()); + server.start(); + } + + public static void clientHttpCalls() throws Exception { + try { + System.out.println("http server listen on: " + server.getAddress().getPort()); + String hostAddr = InetAddress.getLoopbackAddress().getHostAddress(); + if (hostAddr.indexOf(':') > -1) hostAddr = "[" + hostAddr + "]"; + String baseURLStr = "https://" + hostAddr + ":" + server.getAddress().getPort() + "/"; + + URL testUrl = new URL (baseURLStr); + + // SlowCloseSocketFactory is not a real SSLSocketFactory; + // it produces regular non-SSL sockets. Effectively, the request + // is made over http. + HttpsURLConnection.setDefaultSSLSocketFactory(new SlowCloseSocketFactory()); + System.out.println("Performing first request"); + HttpsURLConnection uc = (HttpsURLConnection)testUrl.openConnection(Proxy.NO_PROXY); + byte[] buf = new byte[1024]; + try { + uc.getInputStream(); + throw new RuntimeException("Expected 404 here"); + } catch (FileNotFoundException ignored) { } + try (InputStream is = uc.getErrorStream()) { + while (is.read(buf) >= 0) { + } + } + System.out.println("First request completed"); + closing.await(); + // KeepAliveThread is closing the connection now + System.out.println("Performing second request"); + HttpsURLConnection uc2 = (HttpsURLConnection)testUrl.openConnection(Proxy.NO_PROXY); + + try { + uc2.getInputStream(); + throw new RuntimeException("Expected 404 here"); + } catch (FileNotFoundException ignored) { } + try (InputStream is = uc2.getErrorStream()) { + while (is.read(buf) >= 0) { + } + } + System.out.println("Second request completed"); + // let the socket know it can close now + secondRequestDone.countDown(); + result.get(); + System.out.println("Test completed successfully"); + } finally { + server.stop(1); + } + } + + static class SlowCloseSocket extends SSLSocket { + @Override + public synchronized void close() throws IOException { + String threadName = Thread.currentThread().getName(); + System.out.println("Connection closing, thread name: " + threadName); + closing.countDown(); + super.close(); + if (threadName.equals("Keep-Alive-Timer")) { + try { + if (secondRequestDone.await(5, TimeUnit.SECONDS)) { + result.complete(null); + } else { + result.completeExceptionally(new RuntimeException( + "Wait for second request timed out")); + } + } catch (InterruptedException e) { + result.completeExceptionally(new RuntimeException( + "Wait for second request was interrupted")); + } + } else { + result.completeExceptionally(new RuntimeException( + "Close invoked from unexpected thread")); + } + System.out.println("Connection closed"); + } + + // required abstract method overrides + @Override + public String[] getSupportedCipherSuites() { + return new String[0]; + } + @Override + public String[] getEnabledCipherSuites() { + return new String[0]; + } + @Override + public void setEnabledCipherSuites(String[] suites) { } + @Override + public String[] getSupportedProtocols() { + return new String[0]; + } + @Override + public String[] getEnabledProtocols() { + return new String[0]; + } + @Override + public void setEnabledProtocols(String[] protocols) { } + @Override + public SSLSession getSession() { + return null; + } + @Override + public void addHandshakeCompletedListener(HandshakeCompletedListener listener) { } + @Override + public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) { } + @Override + public void startHandshake() throws IOException { } + @Override + public void setUseClientMode(boolean mode) { } + @Override + public boolean getUseClientMode() { + return false; + } + @Override + public void setNeedClientAuth(boolean need) { } + @Override + public boolean getNeedClientAuth() { + return false; + } + @Override + public void setWantClientAuth(boolean want) { } + @Override + public boolean getWantClientAuth() { + return false; + } + @Override + public void setEnableSessionCreation(boolean flag) { } + @Override + public boolean getEnableSessionCreation() { + return false; + } + } + + static class SlowCloseSocketFactory extends SSLSocketFactory { + + @Override + public Socket createSocket() throws IOException { + return new SlowCloseSocket(); + } + // required abstract method overrides + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + throw new UnsupportedOperationException(); + } + @Override + public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { + throw new UnsupportedOperationException(); + } + @Override + public Socket createSocket(InetAddress host, int port) throws IOException { + throw new UnsupportedOperationException(); + } + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { + throw new UnsupportedOperationException(); + } + @Override + public String[] getDefaultCipherSuites() { + return new String[0]; + } + @Override + public String[] getSupportedCipherSuites() { + return new String[0]; + } + @Override + public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { + throw new UnsupportedOperationException(); + } + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/http/6550798/test.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/http/6550798/test.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/http/6550798/test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/http/6550798/test.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -43,14 +43,15 @@ public static void main(String[] args) throws Exception { TestCache.reset(); - HttpServer s = HttpServer.create (new InetSocketAddress(0), 10); - s.createContext ("/", new HttpHandler () { - public void handle (HttpExchange e) { + InetAddress loopback = InetAddress.getLoopbackAddress(); + HttpServer s = HttpServer.create(new InetSocketAddress(loopback, 0), 10); + s.createContext("/", new HttpHandler() { + public void handle(HttpExchange e) { try { byte[] buf = new byte [LEN]; OutputStream o = e.getResponseBody(); e.sendResponseHeaders(200, LEN); - o.write (buf); + o.write(buf); e.close(); } catch (IOException ex) { ex.printStackTrace(); @@ -91,10 +92,10 @@ } if (TestCache.fail) { - System.out.println ("TEST FAILED"); - throw new RuntimeException (); + System.out.println("TEST FAILED"); + throw new RuntimeException(); } else { - System.out.println ("TEST OK"); + System.out.println("TEST OK"); } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/http/CloseOptionHeader.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/http/CloseOptionHeader.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/http/CloseOptionHeader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/http/CloseOptionHeader.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,6 +25,7 @@ * @test * @bug 6189206 * @modules java.base/sun.net.www + * @library /test/lib * @run main/othervm -Dhttp.keepAlive=false CloseOptionHeader * @summary HTTP client should set "Connection: close" header in request when keepalive is disabled */ @@ -33,7 +34,7 @@ import java.util.*; import java.io.*; import sun.net.www.MessageHeader; - +import jdk.test.lib.net.URIBuilder; public class CloseOptionHeader implements Runnable { static ServerSocket ss; @@ -79,14 +80,20 @@ Thread tester = new Thread(new CloseOptionHeader()); /* start the server */ - ss = new ServerSocket(0); + InetAddress loopback = InetAddress.getLoopbackAddress(); + ss = new ServerSocket(); + ss.bind(new InetSocketAddress(loopback, 0)); tester.start(); /* connect to the server just started * server then check the request to see whether * there is a close connection option header in it */ - URL url = new URL("http://localhost:" + ss.getLocalPort()); + URL url = URIBuilder.newBuilder() + .scheme("http") + .host(ss.getInetAddress()) + .port(ss.getLocalPort()) + .toURL(); HttpURLConnection huc = (HttpURLConnection)url.openConnection(); huc.connect(); huc.getResponseCode(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/AbstractCallback.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/AbstractCallback.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/AbstractCallback.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/AbstractCallback.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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.net.*; -import java.util.*; -import java.io.IOException; - -/** - * This class provides a partial implementation of the HttpCallback - * interface. Use this class if you want to use the requestURI as a means - * of tracking multiple invocations of a request (on the server). - * In this case, you implement the modified request() method, which includes - * an integer count parameter. This parameter indicates the number of times - * (starting at zero) the request URI has been received. - */ - -public abstract class AbstractCallback implements HttpCallback { - - Map requests; - - static class Request { - URI uri; - int count; - - Request (URI u) { - uri = u; - count = 0; - } - } - - AbstractCallback () { - requests = Collections.synchronizedMap (new HashMap()); - } - - /** - * handle the given request and generate an appropriate response. - * @param msg the transaction containing the request from the - * client and used to send the response - */ - public void request (HttpTransaction msg) { - URI uri = msg.getRequestURI(); - Request req = (Request) requests.get (uri); - if (req == null) { - req = new Request (uri); - requests.put (uri, req); - } - request (msg, req.count++); - } - - /** - * Same as HttpCallback interface except that the integer n - * is provided to indicate sequencing of repeated requests using - * the same request URI. n starts at zero and is incremented - * for each successive call. - * - * @param msg the transaction containing the request from the - * client and used to send the response - * @param n value is 0 at first call, and is incremented by 1 for - * each subsequent call using the same request URI. - */ - abstract public void request (HttpTransaction msg, int n); -} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/ChunkedOutputStream.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/ChunkedOutputStream.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/ChunkedOutputStream.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/ChunkedOutputStream.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -24,8 +24,7 @@ /** * @test * @bug 5026745 - * @modules java.base/sun.net.www - * @build TestHttpsServer HttpCallback + * @library /test/lib * @run main/othervm ChunkedOutputStream * * SunJSSE does not support dynamic system properties, no way to re-use @@ -33,11 +32,35 @@ * @summary Cannot flush output stream when writing to an HttpUrlConnection */ -import java.io.*; -import java.net.*; -import javax.net.ssl.*; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpRetryException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.SocketException; +import java.net.URL; +import java.nio.charset.Charset; +import java.security.KeyStore; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManagerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; -public class ChunkedOutputStream implements HttpCallback { +public class ChunkedOutputStream implements HttpHandler { /* * Where do we find the keystores for ssl? */ @@ -46,6 +69,7 @@ static String trustStoreFile = "truststore"; static String passwd = "passphrase"; static int count = 0; + static final AtomicInteger rogueCount = new AtomicInteger(); static final String str1 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+ "1234567890abcdefkjsdlkjflkjsldkfjlsdkjflkj"+ @@ -54,87 +78,100 @@ static final String str2 = "Helloworld1234567890abcdefghijklmnopqrstuvwxyz"+ "1234567890"; - public void request (HttpTransaction req) { - try { - // this is needed (count++ doesn't work), 'cause we - // are doing concurrent tests - String path = req.getRequestURI().getPath(); - if (path.equals("/d0")) { - count = 0; - } else if (path.equals("/d01")) { - count = 1; - } else if (path.equals("/d3")) { - count = 2; - } else if (path.equals("/d4") || path.equals("/d5")) { - count = 3; - } else if (path.equals("/d6")) { - count = 3; - } else if (path.equals("/d7")) { - count = 4; - } else if (path.equals("/d8")) { - count = 5; - } + private static String getAuthority() { + InetAddress address = server.getAddress().getAddress(); + String hostaddr = address.getHostAddress(); + if (address.isAnyLocalAddress()) hostaddr = "localhost"; + if (hostaddr.indexOf(':') > -1) hostaddr = "[" + hostaddr + "]"; + return hostaddr + ":" + server.getAddress().getPort(); + } + + public void handle(HttpExchange req) throws IOException { + // this is needed (count++ doesn't work), 'cause we + // are doing concurrent tests + System.out.println("Request Received"); + String path = req.getRequestURI().getPath(); + if (path.equals("/d0")) { + count = 0; + } else if (path.equals("/d01")) { + count = 1; + } else if (path.equals("/d3")) { + count = 2; + } else if (path.equals("/d4") || path.equals("/d5")) { + count = 3; + } else if (path.equals("/d6")) { + count = 3; + } else if (path.equals("/d7")) { + count = 4; + } else if (path.equals("/d8")) { + count = 5; + } - switch (count) { + switch (count) { case 0: /* test1 -- keeps conn alive */ case 1: /* test2 -- closes conn */ - String reqbody = req.getRequestEntityBody(); + + String reqbody = ""; + try(InputStream inputStream = req.getRequestBody()) { + reqbody = new String(inputStream.readAllBytes(), Charset.forName("ISO8859_1")); + } if (!reqbody.equals(str1)) { - req.sendResponse (500, "Internal server error"); - req.orderlyClose(); + req.sendResponseHeaders(500, -1); + break; } - String chunk = req.getRequestHeader ("Transfer-encoding"); - if (!"chunked".equals (chunk)) { - req.sendResponse (501, "Internal server error"); - req.orderlyClose(); + String chunk = req.getRequestHeaders().getFirst("Transfer-encoding"); + if (!"chunked".equals(chunk)) { + req.sendResponseHeaders(501, -1); + break; } - req.setResponseEntityBody (reqbody); if (count == 1) { - req.setResponseHeader ("Connection", "close"); + req.getResponseHeaders().set("Connection", "close"); } - req.sendResponse (200, "OK"); - if (count == 1) { - req.orderlyClose(); + req.sendResponseHeaders(200, 0); + try (OutputStream os = req.getResponseBody()) { + os.write(reqbody.getBytes(Charset.forName("ISO8859_1"))); } break; case 2: /* test 3 */ - reqbody = req.getRequestEntityBody(); + reqbody = new String(req.getRequestBody().readAllBytes(), Charset.forName("ISO8859_1")); if (!reqbody.equals(str2)) { - req.sendResponse (500, "Internal server error"); - req.orderlyClose(); + req.sendResponseHeaders(500, -1); + break; } - int clen = Integer.parseInt ( - req.getRequestHeader ("Content-length")); + int clen = Integer.parseInt (req.getRequestHeaders().getFirst("Content-length")); if (clen != str2.length()) { - req.sendResponse (501, "Internal server error"); - req.orderlyClose(); + req.sendResponseHeaders(501, -1); + break; + } + req.getResponseHeaders().set("Connection", "close"); + req.sendResponseHeaders(200, 0); + try (OutputStream os = req.getResponseBody()) { + os.write(reqbody.getBytes(Charset.forName("ISO8859_1"))); } - req.setResponseEntityBody (reqbody); - req.setResponseHeader ("Connection", "close"); - req.sendResponse (200, "OK"); - req.orderlyClose(); break; case 3: /* test 6 */ - req.setResponseHeader ("Location", "https://foo.bar/"); - req.setResponseHeader ("Connection", "close"); - req.sendResponse (307, "Temporary Redirect"); - req.orderlyClose(); + if (path.equals("/d6")) { + reqbody = new String(req.getRequestBody().readAllBytes(), Charset.forName("ISO8859_1")); + } + req.getResponseHeaders().set("Location", "https://foo.bar/"); + req.getResponseHeaders().set("Connection", "close"); + req.sendResponseHeaders(307, -1); break; case 4: /* test 7 */ case 5: /* test 8 */ - reqbody = req.getRequestEntityBody(); - if (reqbody != null && !"".equals (reqbody)) { - req.sendResponse (501, "Internal server error"); - req.orderlyClose(); - } - req.setResponseHeader ("Connection", "close"); - req.sendResponse (200, "OK"); - req.orderlyClose(); + reqbody = new String(req.getRequestBody().readAllBytes(), Charset.forName("ISO8859_1")); + if (reqbody != null && !"".equals(reqbody)) { + req.sendResponseHeaders(501, -1); + break; + } + req.getResponseHeaders().set("Connection", "close"); + req.sendResponseHeaders(200, -1); + break; + default: + req.sendResponseHeaders(404, -1); break; - } - } catch (IOException e) { - e.printStackTrace(); } + req.close(); } static void readAndCompare (InputStream is, String cmp) throws IOException { @@ -152,6 +189,23 @@ } } + /* basic smoke test: verify that server drops plain connections */ + static void testPlainText(String authority) throws Exception { + URL url = new URL("http://" + authority + "/Donauschiffsgesellschaftskapitaenskajuete"); + System.out.println("client opening connection to: " + url); + HttpURLConnection urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY); + int rogue = rogueCount.get(); + try { + int code = urlc.getResponseCode(); + System.out.println("Unexpected response: " + code); + throw new AssertionError("Unexpected response: " + code); + } catch (SocketException x) { + // we expect that the server will drop the connection and + // close the accepted socket, so we should get a SocketException + System.out.println("Got expected exception: " + x); + } + } + /* basic chunked test (runs twice) */ static void test1 (String u) throws Exception { @@ -162,7 +216,7 @@ urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); - os.write (str1.getBytes()); + os.write(str1.getBytes(Charset.forName("ISO8859_1"))); os.close(); InputStream is = urlc.getInputStream(); readAndCompare (is, str1); @@ -179,7 +233,7 @@ urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); - os.write (str2.getBytes()); + os.write (str2.getBytes(Charset.forName("ISO8859_1"))); os.close(); InputStream is = urlc.getInputStream(); readAndCompare (is, str2); @@ -196,7 +250,7 @@ urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); - os.write (str2.getBytes()); + os.write(str2.getBytes(Charset.forName("ISO8859_1"))); try { os.close(); throw new Exception ("should have thrown IOException"); @@ -214,7 +268,7 @@ urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); try { - os.write (str2.getBytes()); + os.write(str2.getBytes(Charset.forName("ISO8859_1"))); throw new Exception ("should have thrown IOException"); } catch (IOException e) {} } @@ -229,7 +283,7 @@ urlc.setDoOutput(true); urlc.setRequestMethod ("POST"); OutputStream os = urlc.getOutputStream (); - os.write (str1.getBytes()); + os.write(str1.getBytes(Charset.forName("ISO8859_1"))); os.close(); try { InputStream is = urlc.getInputStream(); @@ -276,9 +330,10 @@ } } - static TestHttpsServer server; + static HttpsServer server; public static void main (String[] args) throws Exception { + ChunkedOutputStream chunkedOutputStream = new ChunkedOutputStream(); // setup properties to do ssl String keyFilename = System.getProperty("test.src", "./") + "/" + pathToStores + @@ -287,6 +342,8 @@ System.getProperty("test.src", "./") + "/" + pathToStores + "/" + trustStoreFile; + InetAddress loopback = InetAddress.getLoopbackAddress(); + HostnameVerifier reservedHV = HttpsURLConnection.getDefaultHostnameVerifier(); try { @@ -297,25 +354,48 @@ HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier()); try { - server = new TestHttpsServer( - new ChunkedOutputStream(), 1, 10, 0); - System.out.println ("Server started: listening on port: " + server.getLocalPort()); + // create and initialize a SSLContext + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + char[] passphrase = "passphrase".toCharArray(); + + ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")), passphrase); + ts.load(new FileInputStream(System.getProperty("javax.net.ssl.trustStore")), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance("TLS"); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + server = HttpsServer.create(new InetSocketAddress(loopback, 0), 10); + server.setHttpsConfigurator(new HttpsConfigurator(sslCtx)); + server.createContext("/", chunkedOutputStream); + server.setExecutor(Executors.newSingleThreadExecutor()); + server.start(); + + System.out.println("Server started: listening on: " + getAuthority()); + testPlainText(getAuthority()); // the test server doesn't support keep-alive yet // test1("http://localhost:"+server.getLocalPort()+"/d0"); - test1("https://localhost:"+server.getLocalPort()+"/d01"); - test3("https://localhost:"+server.getLocalPort()+"/d3"); - test4("https://localhost:"+server.getLocalPort()+"/d4"); - test5("https://localhost:"+server.getLocalPort()+"/d5"); - test6("https://localhost:"+server.getLocalPort()+"/d6"); - test7("https://localhost:"+server.getLocalPort()+"/d7"); - test8("https://localhost:"+server.getLocalPort()+"/d8"); + test1("https://" + getAuthority() + "/d01"); + test3("https://" + getAuthority() + "/d3"); + test4("https://" + getAuthority() + "/d4"); + test5("https://" + getAuthority() + "/d5"); + test6("https://" + getAuthority() + "/d6"); + test7("https://" + getAuthority() + "/d7"); + test8("https://" + getAuthority() + "/d8"); } catch (Exception e) { if (server != null) { - server.terminate(); + server.stop(1); } throw e; } - server.terminate(); + server.stop(1); } finally { HttpsURLConnection.setDefaultHostnameVerifier(reservedHV); } @@ -328,7 +408,7 @@ } public static void except (String s) { - server.terminate(); + server.stop(1); throw new RuntimeException (s); } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpCallback.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpCallback.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpCallback.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpCallback.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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 interface is implemented by classes that wish to handle incoming HTTP - * requests and generate responses. This could be a general purpose HTTP server - * or a test case that expects specific requests from a client. - *

          - * The incoming request fields can be examined via the {@link HttpTransaction} - * object, and a response can also be generated and sent via the request object. - */ -public interface HttpCallback { - /** - * handle the given request and generate an appropriate response. - * @param msg the transaction containing the request from the - * client and used to send the response - */ - void request (HttpTransaction msg); -} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -34,22 +34,39 @@ * @library .. /test/lib * @build jdk.test.lib.NetworkConfiguration * jdk.test.lib.Platform - * HttpCallback TestHttpsServer ClosedChannelList - * HttpTransaction TunnelProxy + * ClosedChannelList + * TunnelProxy * @key intermittent * @run main/othervm B6216082 */ -import java.io.*; -import java.net.*; -import javax.net.ssl.*; -import java.util.*; - +import java.io.FileInputStream; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.NetworkInterface; +import java.net.ProxySelector; +import java.net.URL; +import java.security.KeyStore; +import java.util.Optional; +import java.util.concurrent.Executors; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManagerFactory; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.NetworkConfiguration; public class B6216082 { static SimpleHttpTransaction httpTrans; - static TestHttpsServer server; + static HttpsServer server; static TunnelProxy proxy; // it seems there's no proxy ever if a url points to 'localhost', @@ -66,25 +83,17 @@ if (!setupEnv()) { return; } - startHttpServer(); - // https.proxyPort can only be set after the TunnelProxy has been // created as it will use an ephemeral port. - System.setProperty("https.proxyPort", - (new Integer(proxy.getLocalPort())).toString() ); - + ProxySelector.setDefault(ProxySelector.of(new InetSocketAddress(firstNonLoAddress, proxy.getLocalPort()))); makeHttpCall(); - - if (httpTrans.hasBadRequest) { - throw new RuntimeException("Test failed : bad http request"); - } } finally { if (proxy != null) { proxy.terminate(); } if (server != null) { - server.terminate(); + server.stop(1); } HttpsURLConnection.setDefaultHostnameVerifier(reservedHV); } @@ -135,21 +144,47 @@ return oaddr.orElseGet(() -> null); } - public static void startHttpServer() throws IOException { + public static void startHttpServer() throws Exception { // Both the https server and the proxy let the // system pick up an ephemeral port. httpTrans = new SimpleHttpTransaction(); - server = new TestHttpsServer(httpTrans, 1, 10, 0); + // create and initialize a SSLContext + KeyStore ks = KeyStore.getInstance("JKS"); + KeyStore ts = KeyStore.getInstance("JKS"); + char[] passphrase = "passphrase".toCharArray(); + + ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")), passphrase); + ts.load(new FileInputStream(System.getProperty("javax.net.ssl.trustStore")), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + + SSLContext sslCtx = SSLContext.getInstance("TLS"); + + sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + server = HttpsServer.create(new InetSocketAddress(firstNonLoAddress, 0), 10); + server.setHttpsConfigurator(new HttpsConfigurator(sslCtx)); + server.createContext("/", httpTrans); + server.setExecutor(Executors.newSingleThreadExecutor()); + server.start(); proxy = new TunnelProxy(1, 10, 0); } public static void makeHttpCall() throws Exception { - System.out.println("https server listen on: " + server.getLocalPort()); + System.out.println("https server listen on: " + server.getAddress().getPort()); System.out.println("https proxy listen on: " + proxy.getLocalPort()); URL url = new URL("https" , firstNonLoAddress.getHostAddress(), - server.getLocalPort(), "/"); + server.getAddress().getPort(), "/"); HttpURLConnection uc = (HttpURLConnection)url.openConnection(); System.out.println(uc.getResponseCode()); + if(uc.getResponseCode() != 200) { + uc.disconnect(); + throw new RuntimeException("Test failed : bad http request with response code : "+ uc.getResponseCode()); + } uc.disconnect(); } @@ -160,31 +195,21 @@ } } -class SimpleHttpTransaction implements HttpCallback { - public boolean hasBadRequest = false; +class SimpleHttpTransaction implements HttpHandler { /* * Our http server which simply redirect first call */ - public void request(HttpTransaction trans) { + public void handle(HttpExchange trans) { try { String path = trans.getRequestURI().getPath(); if (path.equals("/")) { // the first call, redirect it String location = "/redirect"; - trans.addResponseHeader("Location", location); - trans.sendResponse(302, "Moved Temporarily"); + trans.getResponseHeaders().set("Location", location); + trans.sendResponseHeaders(302, -1); } else { - // if the bug exsits, it'll send 2 GET commands - // check 2nd GET here - String duplicatedGet = trans.getRequestHeader(null); - if (duplicatedGet != null && - duplicatedGet.toUpperCase().indexOf("GET") >= 0) { - trans.sendResponse(400, "Bad Request"); - hasBadRequest = true; - } else { - trans.sendResponse(200, "OK"); - } + trans.sendResponseHeaders(200, -1); } } catch (Exception e) { throw new RuntimeException(e); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -29,21 +29,25 @@ * @bug 7129083 * @summary Cookiemanager does not store cookies if url is read * before setting cookiemanager + * @library /test/lib * @run main/othervm CookieHttpsClientTest */ import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; +import java.net.InetAddress; import java.net.URL; import java.io.InputStream; import java.io.IOException; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; +import jdk.test.lib.net.URIBuilder; public class CookieHttpsClientTest { static final int TIMEOUT = 10 * 1000; @@ -91,10 +95,11 @@ * to avoid infinite hangs. */ void doServerSide() throws Exception { + InetAddress loopback = InetAddress.getLoopbackAddress(); SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslServerSocket = - (SSLServerSocket) sslssf.createServerSocket(serverPort); + (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback); serverPort = sslServerSocket.getLocalPort(); /* @@ -137,10 +142,17 @@ return true; }}); - URL url = new URL("https://localhost:" + serverPort +"/"); + URL url = URIBuilder.newBuilder() + .scheme("https") + .loopback() + .port(serverPort) + .path("/") + .toURL(); + + System.out.println("Client ready to connect to: " + url); // Run without a CookieHandler first - InputStream in = url.openConnection().getInputStream(); + InputStream in = url.openConnection(java.net.Proxy.NO_PROXY).getInputStream(); while (in.read() != -1); // read response body so connection can be reused // Set a CookeHandler and retest using the HttpClient from the KAC @@ -183,6 +195,10 @@ volatile Exception serverException = null; volatile Exception clientException = null; + private boolean sslConnectionFailed() { + return clientException instanceof SSLHandshakeException; + } + public static void main(String args[]) throws Exception { String keyFilename = System.getProperty("test.src", ".") + "/" + pathToStores + @@ -229,7 +245,11 @@ */ if (separateServerThread) { if (serverThread != null) { - serverThread.join(); + // don't join the server thread if the + // client failed to connect + if (!sslConnectionFailed()) { + serverThread.join(); + } } } else { if (clientThread != null) { @@ -259,7 +279,7 @@ */ if ((local != null) && (remote != null)) { // If both failed, return the curthread's exception. - local.initCause(remote); + local.addSuppressed(remote); exception = local; } else if (local != null) { exception = local; @@ -274,7 +294,7 @@ * output it. */ if (exception != null) { - if (exception != startException) { + if (exception != startException && startException != null) { exception.addSuppressed(startException); } throw exception; @@ -323,7 +343,7 @@ /* * Our client thread just died. */ - System.err.println("Client died..."); + System.err.println("Client died: " + e); clientException = e; } } @@ -333,6 +353,7 @@ try { doClientSide(); } catch (Exception e) { + System.err.println("Client died: " + e); clientException = e; } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -32,12 +32,14 @@ * @summary sun.net.client.defaultConnectTimeout should work with * HttpsURLConnection; HTTP client: Connect and read timeouts; * Https needs to support new tiger features that went into http + * @library /test/lib * @run main/othervm ReadTimeout */ import java.io.*; import java.net.*; import javax.net.ssl.*; +import jdk.test.lib.net.URIBuilder; public class ReadTimeout { @@ -93,10 +95,11 @@ * to avoid infinite hangs. */ void doServerSide() throws Exception { + InetAddress loopback = InetAddress.getLoopbackAddress(); SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslServerSocket = - (SSLServerSocket) sslssf.createServerSocket(serverPort); + (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback); serverPort = sslServerSocket.getLocalPort(); /* @@ -163,7 +166,11 @@ } HttpsURLConnection http = null; try { - URL url = new URL("https://localhost:" + serverPort); + URL url = URIBuilder.newBuilder() + .scheme("https") + .loopback() + .port(serverPort) + .toURL(); // set read timeout through system property System.setProperty("sun.net.client.defaultReadTimeout", "2000"); @@ -184,7 +191,11 @@ } try { - URL url = new URL("https://localhost:" + serverPort); + URL url = URIBuilder.newBuilder() + .scheme("https") + .loopback() + .port(serverPort) + .toURL(); HttpsURLConnection.setDefaultHostnameVerifier( new NameVerifier()); @@ -239,6 +250,10 @@ volatile Exception serverException = null; volatile Exception clientException = null; + private boolean sslConnectionFailed() { + return clientException instanceof SSLHandshakeException; + } + public static void main(String[] args) throws Exception { String keyFilename = System.getProperty("test.src", "./") + "/" + pathToStores + @@ -282,7 +297,9 @@ * Wait for other side to close down. */ if (separateServerThread) { - serverThread.join(); + if (!sslConnectionFailed()) { + serverThread.join(); + } } else { clientThread.join(); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -26,6 +26,7 @@ * @bug 4423074 * @summary Need to rebase all the duplicated classes from Merlin. * This test will check out http POST + * @library /test/lib * @run main/othervm Redirect * * SunJSSE does not support dynamic system properties, no way to re-use @@ -35,6 +36,7 @@ import java.io.*; import java.net.*; import javax.net.ssl.*; +import jdk.test.lib.net.URIBuilder; public class Redirect { @@ -95,10 +97,11 @@ * to avoid infinite hangs. */ void doServerSide() throws Exception { + InetAddress loopback = InetAddress.getLoopbackAddress(); SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslServerSocket = - (SSLServerSocket) sslssf.createServerSocket(serverPort); + (SSLServerSocket) sslssf.createServerSocket(serverPort, 0, loopback); serverPort = sslServerSocket.getLocalPort(); /* @@ -154,7 +157,11 @@ } // Send HTTP POST request to server - URL url = new URL("https://localhost:"+serverPort); + URL url = URIBuilder.newBuilder() + .scheme("https") + .loopback() + .port(serverPort) + .toURL(); HttpsURLConnection.setDefaultHostnameVerifier( new NameVerifier()); @@ -190,6 +197,10 @@ volatile Exception serverException = null; volatile Exception clientException = null; + private boolean sslConnectionFailed() { + return clientException instanceof SSLHandshakeException; + } + public static void main(String[] args) throws Exception { String keyFilename = System.getProperty("test.src", "./") + "/" + pathToStores + @@ -233,7 +244,9 @@ * Wait for other side to close down. */ if (separateServerThread) { - serverThread.join(); + if (!sslConnectionFailed()) { + serverThread.join(); + } } else { clientThread.join(); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,12 +25,27 @@ * */ -import java.net.*; -import java.io.*; -import java.nio.*; -import java.nio.channels.*; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.BufferOverflowException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + import sun.net.www.MessageHeader; -import java.util.*; public class TunnelProxy { @@ -43,7 +58,6 @@ * Create a TunnelProxy instance with the specified callback object * for handling requests. One thread is created to handle requests, * and up to ten TCP connections will be handled simultaneously. - * @param cb the callback object which is invoked to handle each * incoming request */ @@ -55,8 +69,6 @@ * Create a TunnelProxy instance with the specified number of * threads and maximum number of connections per thread. This functions * the same as the 4 arg constructor, where the port argument is set to zero. - * @param cb the callback object which is invoked to handle each - * incoming request * @param threads the number of threads to create to handle requests * in parallel * @param cperthread the number of simultaneous TCP connections to @@ -74,8 +86,6 @@ * the specified port. The specified number of threads are created to * handle incoming requests, and each thread is allowed * to handle a number of simultaneous TCP connections. - * @param cb the callback object which is invoked to handle - * each incoming request * @param threads the number of threads to create to handle * requests in parallel * @param cperthread the number of simultaneous TCP connections @@ -228,7 +238,6 @@ /* return true if the connection is closed, false otherwise */ private boolean read (SocketChannel chan, SelectionKey key) { - HttpTransaction msg; boolean res; try { InputStream is = new BufferedInputStream (new NioInputStream (chan)); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpTransaction.java openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpTransaction.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/net/www/protocol/https/HttpTransaction.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/net/www/protocol/https/HttpTransaction.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,330 +0,0 @@ -/* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please 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.nio.*; -import java.nio.channels.*; -import java.net.*; -import sun.net.www.MessageHeader; - -/** - * This class encapsulates a HTTP request received and a response to be - * generated in one transaction. It provides methods for examaining the - * request from the client, and for building and sending a reply. - */ - -public class HttpTransaction { - - String command; - URI requesturi; - TestHttpsServer.ServerWorker server; - MessageHeader reqheaders, reqtrailers; - String reqbody; - byte[] rspbody; - MessageHeader rspheaders, rsptrailers; - SocketChannel ch; - int rspbodylen; - boolean rspchunked; - - HttpTransaction (TestHttpsServer.ServerWorker server, String command, - URI requesturi, MessageHeader headers, - String body, MessageHeader trailers, SocketChannel ch) { - this.command = command; - this.requesturi = requesturi; - this.reqheaders = headers; - this.reqbody = body; - this.reqtrailers = trailers; - this.ch = ch; - this.server = server; - } - - /** - * Get the value of a request header whose name is specified by the - * String argument. - * - * @param key the name of the request header - * @return the value of the header or null if it does not exist - */ - public String getRequestHeader (String key) { - return reqheaders.findValue (key); - } - - /** - * Get the value of a response header whose name is specified by the - * String argument. - * - * @param key the name of the response header - * @return the value of the header or null if it does not exist - */ - public String getResponseHeader (String key) { - return rspheaders.findValue (key); - } - - /** - * Get the request URI - * - * @return the request URI - */ - public URI getRequestURI () { - return requesturi; - } - - public String toString () { - StringBuffer buf = new StringBuffer(); - buf.append ("Request from: ").append (ch.toString()).append("\r\n"); - buf.append ("Command: ").append (command).append("\r\n"); - buf.append ("Request URI: ").append (requesturi).append("\r\n"); - buf.append ("Headers: ").append("\r\n"); - buf.append (reqheaders.toString()).append("\r\n"); - buf.append ("Body: ").append (reqbody).append("\r\n"); - buf.append ("---------Response-------\r\n"); - buf.append ("Headers: ").append("\r\n"); - if (rspheaders != null) { - buf.append (rspheaders.toString()).append("\r\n"); - } - String rbody = rspbody == null? "": new String (rspbody); - buf.append ("Body: ").append (rbody).append("\r\n"); - return new String (buf); - } - - /** - * Get the value of a request trailer whose name is specified by - * the String argument. - * - * @param key the name of the request trailer - * @return the value of the trailer or null if it does not exist - */ - public String getRequestTrailer (String key) { - return reqtrailers.findValue (key); - } - - /** - * Add a response header to the response. Multiple calls with the same - * key value result in multiple header lines with the same key identifier - * @param key the name of the request header to add - * @param val the value of the header - */ - public void addResponseHeader (String key, String val) { - if (rspheaders == null) - rspheaders = new MessageHeader (); - rspheaders.add (key, val); - } - - /** - * Set a response header. Searches for first header with named key - * and replaces its value with val - * @param key the name of the request header to add - * @param val the value of the header - */ - public void setResponseHeader (String key, String val) { - if (rspheaders == null) - rspheaders = new MessageHeader (); - rspheaders.set (key, val); - } - - /** - * Add a response trailer to the response. Multiple calls with the same - * key value result in multiple trailer lines with the same key identifier - * @param key the name of the request trailer to add - * @param val the value of the trailer - */ - public void addResponseTrailer (String key, String val) { - if (rsptrailers == null) - rsptrailers = new MessageHeader (); - rsptrailers.add (key, val); - } - - /** - * Get the request method - * - * @return the request method - */ - public String getRequestMethod (){ - return command; - } - - /** - * Perform an orderly close of the TCP connection associated with this - * request. This method guarantees that any response already sent will - * not be reset (by this end). The implementation does a shutdownOutput() - * of the TCP connection and for a period of time consumes and discards - * data received on the reading side of the connection. This happens - * in the background. After the period has expired the - * connection is completely closed. - */ - - public void orderlyClose () { - try { - server.orderlyCloseChannel (ch); - } catch (IOException e) { - System.out.println (e); - } - } - - /** - * Do an immediate abortive close of the TCP connection associated - * with this request. - */ - public void abortiveClose () { - try { - server.abortiveCloseChannel(ch); - } catch (IOException e) { - System.out.println (e); - } - } - - /** - * Get the SocketChannel associated with this request - * - * @return the socket channel - */ - public SocketChannel channel() { - return ch; - } - - /** - * Get the request entity body associated with this request - * as a single String. - * - * @return the entity body in one String - */ - public String getRequestEntityBody (){ - return reqbody; - } - - /** - * Set the entity response body with the given string - * The content length is set to the length of the string - * @param body the string to send in the response - */ - public void setResponseEntityBody (String body){ - rspbody = body.getBytes(); - rspbodylen = body.length(); - rspchunked = false; - addResponseHeader ("Content-length", Integer.toString (rspbodylen)); - } - /** - * Set the entity response body with the given byte[] - * The content length is set to the gven length - * @param body the string to send in the response - */ - public void setResponseEntityBody (byte[] body, int len){ - rspbody = body; - rspbodylen = len; - rspchunked = false; - addResponseHeader ("Content-length", Integer.toString (rspbodylen)); - } - - - /** - * Set the entity response body by reading the given inputstream - * - * @param is the inputstream from which to read the body - */ - public void setResponseEntityBody (InputStream is) throws IOException { - byte[] buf = new byte [2048]; - byte[] total = new byte [2048]; - int total_len = 2048; - int c, len=0; - while ((c=is.read (buf)) != -1) { - if (len+c > total_len) { - byte[] total1 = new byte [total_len * 2]; - System.arraycopy (total, 0, total1, 0, len); - total = total1; - total_len = total_len * 2; - } - System.arraycopy (buf, 0, total, len, c); - len += c; - } - setResponseEntityBody (total, len); - } - - /* chunked */ - - /** - * Set the entity response body with the given array of strings - * The content encoding is set to "chunked" and each array element - * is sent as one chunk. - * @param body the array of string chunks to send in the response - */ - public void setResponseEntityBody (String[] body) { - StringBuffer buf = new StringBuffer (); - int len = 0; - for (int i=0; i - * It must be instantiated with a {@link HttpCallback} object to which - * requests are given and must be handled. - *

          - * Simple synchronization between the client(s) and server can be done - * using the {@link #waitForCondition(String)}, {@link #setCondition(String)} and - * {@link #rendezvous(String,int)} methods. - * - * NOTE NOTE NOTE NOTE NOTE NOTE NOTE - * - * If you make a change in here, please don't forget to make the - * corresponding change in the J2SE equivalent. - * - * NOTE NOTE NOTE NOTE NOTE NOTE NOTE - */ - -public class TestHttpsServer { - - ServerSocketChannel schan; - int threads; - int cperthread; - HttpCallback cb; - Server[] servers; - - // ssl related fields - static SSLContext sslCtx; - - /** - * Create a TestHttpsServer instance with the specified callback object - * for handling requests. One thread is created to handle requests, - * and up to ten TCP connections will be handled simultaneously. - * @param cb the callback object which is invoked to handle each - * incoming request - */ - - public TestHttpsServer (HttpCallback cb) throws IOException { - this (cb, 1, 10, 0); - } - - /** - * Create a TestHttpsServer instance with the specified number of - * threads and maximum number of connections per thread. This functions - * the same as the 4 arg constructor, where the port argument is set to zero. - * @param cb the callback object which is invoked to handle each - * incoming request - * @param threads the number of threads to create to handle requests - * in parallel - * @param cperthread the number of simultaneous TCP connections to - * handle per thread - */ - - public TestHttpsServer (HttpCallback cb, int threads, int cperthread) - throws IOException { - this (cb, threads, cperthread, 0); - } - - /** - * Create a TestHttpsServer instance with the specified number - * of threads and maximum number of connections per thread and running on - * the specified port. The specified number of threads are created to - * handle incoming requests, and each thread is allowed - * to handle a number of simultaneous TCP connections. - * @param cb the callback object which is invoked to handle - * each incoming request - * @param threads the number of threads to create to handle - * requests in parallel - * @param cperthread the number of simultaneous TCP connections - * to handle per thread - * @param port the port number to bind the server to. Zero - * means choose any free port. - */ - - public TestHttpsServer (HttpCallback cb, int threads, int cperthread, int port) - throws IOException { - schan = ServerSocketChannel.open (); - InetSocketAddress addr = new InetSocketAddress (port); - schan.socket().bind (addr); - this.threads = threads; - this.cb = cb; - this.cperthread = cperthread; - - try { - // create and initialize a SSLContext - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); - char[] passphrase = "passphrase".toCharArray(); - - ks.load(new FileInputStream(System.getProperty("javax.net.ssl.keyStore")), passphrase); - ts.load(new FileInputStream(System.getProperty("javax.net.ssl.trustStore")), passphrase); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, passphrase); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ts); - - sslCtx = SSLContext.getInstance("TLS"); - - sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - - servers = new Server [threads]; - for (int i=0; i 0 && ((c=is.read (buf, off, remain))>0)) { - remain -= c; - off += c; - } - return buf; - } - - private void readCRLF(InputStream is) throws IOException { - int cr = is.read(); - int lf = is.read(); - - if (((cr & 0xff) != 0x0d) || - ((lf & 0xff) != 0x0a)) { - throw new IOException( - "Expected : got '" + cr + "/" + lf + "'"); - } - } - - byte[] readChunkedData (InputStream is) throws IOException { - LinkedList l = new LinkedList (); - int total = 0; - for (int len=readChunkLen(is); len!=0; len=readChunkLen(is)) { - l.add (readNormalData(is, len)); - total += len; - readCRLF(is); // CRLF at end of chunk - } - readCRLF(is); // CRLF at end of Chunked Stream. - byte[] buf = new byte [total]; - Iterator i = l.iterator(); - int x = 0; - while (i.hasNext()) { - byte[] b = (byte[])i.next(); - System.arraycopy (b, 0, buf, x, b.length); - x += b.length; - } - return buf; - } - - private int readChunkLen (InputStream is) throws IOException { - int c, len=0; - boolean done=false, readCR=false; - while (!done) { - c = is.read (); - if (c == '\n' && readCR) { - done = true; - } else { - if (c == '\r' && !readCR) { - readCR = true; - } else { - int x=0; - if (c >= 'a' && c <= 'f') { - x = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - x = c - 'A' + 10; - } else if (c >= '0' && c <= '9') { - x = c - '0'; - } - len = len * 16 + x; - } - } - } - return len; - } - - private String readLine (InputStream is) throws IOException { - boolean done=false, readCR=false; - byte[] b = new byte [512]; - int c, l = 0; - - while (!done) { - c = is.read (); - if (c == '\n' && readCR) { - done = true; - } else { - if (c == '\r' && !readCR) { - readCR = true; - } else { - b[l++] = (byte)c; - } - } - } - return new String (b); - } - - /** close the channel associated with the current key by: - * 1. shutdownOutput (send a FIN) - * 2. mark the key so that incoming data is to be consumed and discarded - * 3. After a period, close the socket - */ - - synchronized void orderlyCloseChannel (SocketChannel ch) throws IOException { - ch.socket().shutdownOutput(); - } - - synchronized void abortiveCloseChannel (SocketChannel ch) throws IOException { - Socket s = ch.socket (); - s.setSoLinger (true, 0); - ch.close(); - } - } - - - /** - * Implements blocking reading semantics on top of a non-blocking channel - */ - - static class NioInputStream extends InputStream { - SSLEngine sslEng; - SocketChannel channel; - Selector selector; - ByteBuffer inNetBB; - ByteBuffer inAppBB; - SelectionKey key; - int available; - byte[] one; - boolean closed; - ByteBuffer markBuf; /* reads may be satisifed from this buffer */ - boolean marked; - boolean reset; - int readlimit; - - public NioInputStream (SocketChannel chan, SSLEngine sslEng, ByteBuffer inNetBB, ByteBuffer inAppBB) throws IOException { - this.sslEng = sslEng; - this.channel = chan; - selector = Selector.open(); - this.inNetBB = inNetBB; - this.inAppBB = inAppBB; - key = chan.register (selector, SelectionKey.OP_READ); - available = 0; - one = new byte[1]; - closed = marked = reset = false; - } - - public synchronized int read (byte[] b) throws IOException { - return read (b, 0, b.length); - } - - public synchronized int read () throws IOException { - return read (one, 0, 1); - } - - public synchronized int read (byte[] b, int off, int srclen) throws IOException { - - int canreturn, willreturn; - - if (closed) - return -1; - - if (reset) { /* satisfy from markBuf */ - canreturn = markBuf.remaining (); - willreturn = canreturn>srclen ? srclen : canreturn; - markBuf.get(b, off, willreturn); - if (canreturn == willreturn) { - reset = false; - } - } else { /* satisfy from channel */ - canreturn = available(); - if (canreturn == 0) { - block (); - canreturn = available(); - } - willreturn = canreturn>srclen ? srclen : canreturn; - inAppBB.get(b, off, willreturn); - available -= willreturn; - - if (marked) { /* copy into markBuf */ - try { - markBuf.put (b, off, willreturn); - } catch (BufferOverflowException e) { - marked = false; - } - } - } - return willreturn; - } - - public synchronized int available () throws IOException { - if (closed) - throw new IOException ("Stream is closed"); - - if (reset) - return markBuf.remaining(); - - if (available > 0) - return available; - - inAppBB.clear (); - int bytes = channel.read (inNetBB); - - int needed = sslEng.getSession().getApplicationBufferSize(); - if (needed > inAppBB.remaining()) { - inAppBB = ByteBuffer.allocate(needed); - } - inNetBB.flip(); - SSLEngineResult result = sslEng.unwrap(inNetBB, inAppBB); - inNetBB.compact(); - available = result.bytesProduced(); - - if (available > 0) - inAppBB.flip(); - else if (available == -1) - throw new IOException ("Stream is closed"); - return available; - } - - /** - * block() only called when available==0 and buf is empty - */ - private synchronized void block () throws IOException { - //assert available == 0; - int n = selector.select (); - //assert n == 1; - selector.selectedKeys().clear(); - available (); - } - - public void close () throws IOException { - if (closed) - return; - channel.close (); - closed = true; - } - - public synchronized void mark (int readlimit) { - if (closed) - return; - this.readlimit = readlimit; - markBuf = ByteBuffer.allocate (readlimit); - marked = true; - reset = false; - } - - public synchronized void reset () throws IOException { - if (closed ) - return; - if (!marked) - throw new IOException ("Stream not marked"); - marked = false; - reset = true; - markBuf.flip (); - } - } - - static class NioOutputStream extends OutputStream { - SSLEngine sslEng; - SocketChannel channel; - ByteBuffer outNetBB; - ByteBuffer outAppBB; - SelectionKey key; - Selector selector; - boolean closed; - byte[] one; - - public NioOutputStream (SocketChannel channel, SSLEngine sslEng, ByteBuffer outNetBB, ByteBuffer outAppBB) throws IOException { - this.sslEng = sslEng; - this.channel = channel; - this.outNetBB = outNetBB; - this.outAppBB = outAppBB; - selector = Selector.open (); - key = channel.register (selector, SelectionKey.OP_WRITE); - closed = false; - one = new byte [1]; - } - - public synchronized void write (int b) throws IOException { - one[0] = (byte)b; - write (one, 0, 1); - } - - public synchronized void write (byte[] b) throws IOException { - write (b, 0, b.length); - } - - public synchronized void write (byte[] b, int off, int len) throws IOException { - if (closed) - throw new IOException ("stream is closed"); - - outAppBB = ByteBuffer.allocate (len); - outAppBB.put (b, off, len); - outAppBB.flip (); - int n; - outNetBB.clear(); - int needed = sslEng.getSession().getPacketBufferSize(); - if (outNetBB.capacity() < needed) { - outNetBB = ByteBuffer.allocate(needed); - } - SSLEngineResult ret = sslEng.wrap(outAppBB, outNetBB); - outNetBB.flip(); - int newLen = ret.bytesProduced(); - while ((n = channel.write (outNetBB)) < newLen) { - newLen -= n; - if (newLen == 0) - return; - selector.select (); - selector.selectedKeys().clear (); - } - } - - public void close () throws IOException { - if (closed) - return; - channel.close (); - closed = true; - } - } - - /** - * Utilities for synchronization. A condition is - * identified by a string name, and is initialized - * upon first use (ie. setCondition() or waitForCondition()). Threads - * are blocked until some thread calls (or has called) setCondition() for the same - * condition. - *

          - * A rendezvous built on a condition is also provided for synchronizing - * N threads. - */ - - private static HashMap conditions = new HashMap(); - - /* - * Modifiable boolean object - */ - private static class BValue { - boolean v; - } - - /* - * Modifiable int object - */ - private static class IValue { - int v; - IValue (int i) { - v =i; - } - } - - - private static BValue getCond (String condition) { - synchronized (conditions) { - BValue cond = (BValue) conditions.get (condition); - if (cond == null) { - cond = new BValue(); - conditions.put (condition, cond); - } - return cond; - } - } - - /** - * Set the condition to true. Any threads that are currently blocked - * waiting on the condition, will be unblocked and allowed to continue. - * Threads that subsequently call waitForCondition() will not block. - * If the named condition did not exist prior to the call, then it is created - * first. - */ - - public static void setCondition (String condition) { - BValue cond = getCond (condition); - synchronized (cond) { - if (cond.v) { - return; - } - cond.v = true; - cond.notifyAll(); - } - } - - /** - * If the named condition does not exist, then it is created and initialized - * to false. If the condition exists or has just been created and its value - * is false, then the thread blocks until another thread sets the condition. - * If the condition exists and is already set to true, then this call returns - * immediately without blocking. - */ - - public static void waitForCondition (String condition) { - BValue cond = getCond (condition); - synchronized (cond) { - if (!cond.v) { - try { - cond.wait(); - } catch (InterruptedException e) {} - } - } - } - - /* conditions must be locked when accessing this */ - static HashMap rv = new HashMap(); - - /** - * Force N threads to rendezvous (ie. wait for each other) before proceeding. - * The first thread(s) to call are blocked until the last - * thread makes the call. Then all threads continue. - *

          - * All threads that call with the same condition name, must use the same value - * for N (or the results may be not be as expected). - *

          - * Obviously, if fewer than N threads make the rendezvous then the result - * will be a hang. - */ - - public static void rendezvous (String condition, int N) { - BValue cond; - IValue iv; - String name = "RV_"+condition; - - /* get the condition */ - - synchronized (conditions) { - cond = (BValue)conditions.get (name); - if (cond == null) { - /* we are first caller */ - if (N < 2) { - throw new RuntimeException ("rendezvous must be called with N >= 2"); - } - cond = new BValue (); - conditions.put (name, cond); - iv = new IValue (N-1); - rv.put (name, iv); - } else { - /* already initialised, just decrement the counter */ - iv = (IValue) rv.get (name); - iv.v --; - } - } - - if (iv.v > 0) { - waitForCondition (name); - } else { - setCondition (name); - synchronized (conditions) { - clearCondition (name); - rv.remove (name); - } - } - } - - /** - * If the named condition exists and is set then remove it, so it can - * be re-initialized and used again. If the condition does not exist, or - * exists but is not set, then the call returns without doing anything. - * Note, some higher level synchronization - * may be needed between clear and the other operations. - */ - - public static void clearCondition(String condition) { - BValue cond; - synchronized (conditions) { - cond = (BValue) conditions.get (condition); - if (cond == null) { - return; - } - synchronized (cond) { - if (cond.v) { - conditions.remove (condition); - } - } - } - } -} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java openjdk-lts-11.0.21+9/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/jgss/spnego/NotPreferredMech.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048194 + * @bug 8048194 8242151 * @modules java.base/sun.security.util * java.security.jgss/sun.security.jgss * java.security.jgss/sun.security.jgss.spnego:+open @@ -57,7 +57,7 @@ mechTypeList.write(DerValue.tag_Sequence, mech); // Generates a NegTokenInit mechToken field for 1.2.3.4 mech - GSSHeader h1 = new GSSHeader(new ObjectIdentifier("1.2.3.4"), 1); + GSSHeader h1 = new GSSHeader(ObjectIdentifier.of("1.2.3.4"), 1); ByteArrayOutputStream bout = new ByteArrayOutputStream(); h1.encode(bout); bout.write(new byte[1]); @@ -78,7 +78,7 @@ // and wraps it into a GSSToken GSSHeader h = new GSSHeader( - new ObjectIdentifier(GSSUtil.GSS_SPNEGO_MECH_OID.toString()), + ObjectIdentifier.of(GSSUtil.GSS_SPNEGO_MECH_OID.toString()), spnegoToken.length); bout = new ByteArrayOutputStream(); h.encode(bout); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/krb5/auto/Unavailable.java openjdk-lts-11.0.21+9/test/jdk/sun/security/krb5/auto/Unavailable.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/krb5/auto/Unavailable.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/krb5/auto/Unavailable.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,80 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8274205 + * @summary Handle KDC_ERR_SVC_UNAVAILABLE error code from KDC + * @library /test/lib + * @compile -XDignore.symbol.file Unavailable.java + * @run main jdk.test.lib.FileInstaller TestHosts TestHosts + * @run main/othervm -Djdk.net.hosts.file=TestHosts Unavailable + */ + +import sun.security.krb5.Config; +import sun.security.krb5.PrincipalName; +import sun.security.krb5.internal.KRBError; +import sun.security.krb5.internal.KerberosTime; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Locale; + +public class Unavailable { + + public static void main(String[] args) throws Exception { + + // Good KDC + KDC kdc1 = KDC.create(OneKDC.REALM); + kdc1.addPrincipal(OneKDC.USER, OneKDC.PASS); + kdc1.addPrincipalRandKey("krbtgt/" + OneKDC.REALM); + + // The "not available" KDC + KDC kdc2 = new KDC(OneKDC.REALM, "kdc." + OneKDC.REALM.toLowerCase(Locale.US), 0, true) { + @Override + protected byte[] processAsReq(byte[] in) throws Exception { + KRBError err = new KRBError(null, null, null, + KerberosTime.now(), 0, + 29, // KDC_ERR_SVC_UNAVAILABLE + null, new PrincipalName("krbtgt/" + OneKDC.REALM), + null, null); + return err.asn1Encode(); + } + }; + + Files.write(Path.of(OneKDC.KRB5_CONF), String.format( + "[libdefaults]\n" + + "default_realm = RABBIT.HOLE\n" + + "\n" + + "[realms]\n" + + "RABBIT.HOLE = {\n" + + " kdc = kdc.rabbit.hole:%d\n" + + " kdc = kdc.rabbit.hole:%d\n" + + "}\n", + kdc2.getPort(), kdc1.getPort()).getBytes()); + System.setProperty("java.security.krb5.conf", OneKDC.KRB5_CONF); + Config.refresh(); + + Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java openjdk-lts-11.0.21+9/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java 2023-10-06 05:33:33.000000000 +0000 @@ -28,7 +28,7 @@ * 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136 * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 - * 8305975 8304760 8307134 + * 8305975 8304760 8307134 8295894 8314960 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -52,8 +52,7 @@ // 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 - = "72:C7:B8:9E:54:94:D2:D9:C0:E5:9F:F7:C3:8C:3B:18:D7:42:23:82:51:F2:AD:A1:14:26:E0:4A:F2:5F:AE:80"; - + = "88:72:92:56:FF:E5:A3:E4:39:98:6D:18:0B:BA:CC:0B:66:CB:1D:6D:52:CE:D7:C8:AD:63:B7:F1:5F:02:24:52"; // map of cert alias to SHA-256 fingerprint @SuppressWarnings("serial") private static final Map FINGERPRINT_MAP = new HashMap<>() { @@ -158,8 +157,6 @@ "18:F1:FC:7F:20:5D:F8:AD:DD:EB:7F:E0:07:DD:57:E3:AF:37:5A:9C:4D:8D:73:54:6B:F4:F1:FE:D1:E1:8D:35"); put("quovadisrootca3g3 [jdk]", "88:EF:81:DE:20:2E:B0:18:45:2E:43:F8:64:72:5C:EA:5F:BD:1F:C2:D9:D2:05:73:07:09:C5:D8:B8:69:0F:46"); - put("secomscrootca1 [jdk]", - "E7:5E:72:ED:9F:56:0E:EC:6E:B4:80:00:73:A4:3F:C3:AD:19:19:5A:39:22:82:01:78:95:97:4A:99:02:6B:6C"); put("secomscrootca2 [jdk]", "51:3B:2C:EC:B8:10:D4:CD:E5:DD:85:39:1A:DF:C6:C2:DD:60:D8:7B:B7:36:D2:B5:21:48:4A:A4:7A:0E:BE:F6"); put("swisssigngoldg2ca [jdk]", @@ -252,6 +249,8 @@ "34:D8:A7:3E:E2:08:D9:BC:DB:0D:95:65:20:93:4B:4E:40:E6:94:82:59:6E:8B:6F:73:C8:42:6B:01:0A:6F:48"); put("gtsrootecccar4 [jdk]", "34:9D:FA:40:58:C5:E2:63:12:3B:39:8A:E7:95:57:3C:4E:13:13:C8:3F:E6:8F:93:55:6C:D5:E8:03:1B:3C:7D"); + put("certignarootca [jdk]", + "D4:8D:3D:23:EE:DB:50:A4:59:E5:51:97:60:1C:27:77:4B:9D:7B:18:C9:4D:5A:05:95:11:A1:02:50:B9:31:68"); } }; @@ -290,8 +289,8 @@ String checksum = toHexString(md.digest(data)); if (!checksum.equals(CHECKSUM)) { atLeastOneFailed = true; - System.err.println("ERROR: wrong checksum" + checksum); - System.err.println("Expected checksum" + CHECKSUM); + System.err.println("ERROR: wrong checksum " + checksum); + System.err.println("Expected checksum " + CHECKSUM); } KeyStore ks = KeyStore.getInstance("JKS"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttrEncoding.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048357 + * @bug 8048357 8242151 * @summary test DER encoding of PKCS10 attributes * @modules java.base/sun.security.pkcs * java.base/sun.security.pkcs10 @@ -62,7 +62,7 @@ // initializations int len = ids.length; Object[] values = { - new ObjectIdentifier("1.2.3.4"), + ObjectIdentifier.of("1.2.3.4"), new GregorianCalendar(1970, 1, 25, 8, 56, 7).getTime(), "challenging" }; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs/pkcs10/PKCS10AttributeReader.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8048357 + * @bug 8048357 8242151 * @summary Read in a file containing a DER encoded PKCS10 certificate request, * flanked with "begin" and "end" lines. * @modules java.base/sun.security.pkcs @@ -86,7 +86,7 @@ put(PKCS9Attribute.CHALLENGE_PASSWORD_OID, "GuessWhoAmI"); put(PKCS9Attribute.SIGNING_TIME_OID, new Date(861720610000L)); put(PKCS9Attribute.CONTENT_TYPE_OID, - new ObjectIdentifier("1.9.50.51.52")); + ObjectIdentifier.of("1.9.50.51.52")); } }; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs11/Cipher/TestKATForGCM.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs11/Cipher/TestKATForGCM.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs11/Cipher/TestKATForGCM.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs11/Cipher/TestKATForGCM.java 2023-10-06 05:33:33.000000000 +0000 @@ -30,12 +30,13 @@ * @summary Known Answer Test for AES cipher with GCM mode support in * PKCS11 provider. */ -import java.security.*; -import javax.crypto.*; -import javax.crypto.spec.*; -import java.math.*; - -import java.util.*; +import java.security.GeneralSecurityException; +import java.security.Provider; +import java.util.Arrays; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.SecretKeySpec; public class TestKATForGCM extends PKCS11Test { @@ -307,15 +308,21 @@ System.out.println("Test Passed!"); } } catch (Exception e) { - double ver = getNSSInfo("nss"); - if (ver < 3.251d && p.getName().contains("SunPKCS11-NSS") && - System.getProperty("os.name").equals("SunOS")) { - // buggy behaviour from solaris on 11.2 OS (nss < 3.251) - System.out.println("Skipping: SunPKCS11-NSS: Old NSS: " + ver); - return; // OK - } else { - throw e; + System.out.println("Exception occured using " + p.getName() + " version " + p.getVersionStr()); + + if (isNSS(p)) { + double ver = getNSSInfo("nss"); + String osName = System.getProperty("os.name"); + if (ver < 3.251d && osName.equals("SunOS")) { + // buggy behaviour from solaris on 11.2 OS (nss < 3.251) + System.out.println("Skipping: SunPKCS11-NSS: Old NSS: " + ver); + return; // OK + } else if (ver > 3.139 && ver < 3.15 && osName.equals("Linux")) { + // warn about buggy behaviour on Linux with nss 3.14 + System.out.println("Warning: old NSS " + ver + " might be problematic, consider upgrading it"); + } } + throw e; } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs11/PKCS11Test.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs11/PKCS11Test.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs11/PKCS11Test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs11/PKCS11Test.java 2023-10-06 05:33:33.000000000 +0000 @@ -988,21 +988,21 @@ @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-windows_x64", - revision = "3.41-VS2017", + revision = "3.46-VS2017", extension = "zip") private static class WINDOWS_X64 { } @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-windows_x86", - revision = "3.41-VS2017", + revision = "3.46-VS2017", extension = "zip") private static class WINDOWS_X86 { } @Artifact( organization = "jpg.tests.jdk.nsslib", name = "nsslib-macosx_x64", - revision = "3.41", + revision = "3.46", extension = "zip") private static class MACOSX_X64 { } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs11/rsa/TestKeyFactory.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs11/rsa/TestKeyFactory.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs11/rsa/TestKeyFactory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs11/rsa/TestKeyFactory.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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,7 +23,7 @@ /* * @test - * @bug 4856966 + * @bug 4856966 8023980 * @summary Test KeyFactory of the new RSA provider * @author Andreas Sterbenz * @library /test/lib .. @@ -42,6 +42,84 @@ private static final char[] password = "test12".toCharArray(); + private static final String PKCS1_PRIV_STR = + // the BASE64 string between -----BEGIN RSA PRIVATE KEY----- + // and -----END RSA PRIVATE KEY----- + "MIIEowIBAAKCAQEA0OIArlYES4X1XMTLDordtN/XIWFE1wvhl40RsHWM2n99+Stp" + + "CCJCcUb5FJ2/kefj/XRwB6p5IMpIZrHZqC8XXzlX5fpiFaSu2xnk17oWUKoErW27" + + "Stm098pU2RoUxWPKVl+42a8iVp8tijNElBNFALCGi0zXOhcTxMh0q1Wk0UhMJqam" + + "v5YnCKmT4THwwGYn/KeK3M7Qa+o5MoVBHLbeT9LJgEmSluVzIh44Lh6weX0bw72P" + + "8X2praOhbzg2B343MqS/rMLw6On+0i7ccEgp23vX9G5w85q4A5FSIrk4S/pyv5sO" + + "rwjCQKBW1TS0/2iB9zNkFMj5/+h7l2oqTT7sSQIDAQABAoIBADn6sXOynoiUC1IP" + + "sck8lGOTSjSSujfyrVCSsJlJV6qCfuX9va6rS8QDjjnBu531PtxoSHxoPizy2Pvg" + + "W+kKATPGR/am9DjLuFlKq7GRjoYfWyMEdVtGaKvq9ng4fBF6LHyjHz0VFrPyhQJ6" + + "TovHeXzCguYBkzAlnbAeb/vqzs/kABbOuSHVi7DsaixCoEX9zOptFYQw/l8rh68+" + + "UF2bpNNH3jOC1uN3vZtuSwCupqtN+2Mpkx2h04Rk75vWIhrnPeMgmcd3yP4LNZMR" + + "mfaynb63RRzVkNis7+NVk016SQ1oL79mrBvy5rBg3HeCeArwvqZAmOaWsLSWHzCy" + + "zlVlMTECgYEA6JlnMpC956Qi8HX5ye4Hu2ovBdbNGtH/TMkZmColJz9P7CvNkNIb" + + "Od6mvLMydbPHkhdBUDWD4rhiCKHrf5zKju1i24YqWcvuSGotWj4/KQ3+87mLZM+7" + + "daBsJBmSEVB80sgA9ItqSgOyNoNFpiDgFnlszAfb0n9XXEzB/pwSw1UCgYEA5eXI" + + "d+eKugugP+n6CluQfyxfN6WWCzfqWToCTTxPn2i12AiEssXy+kyLjupJVLWSivdo" + + "83wD5LuxFRGc9P+aKQERPhb0AFaxf1llUCXla65/x2So5xjMvtuzgQ0OktPJqJXq" + + "hYGunctsr5rje33+7vlx4xWkrL2PrQWzJabn7SUCgYEAqw3FesY/Ik7u8u+P1xSZ" + + "0xXvptek1oiAu7NYgzLbR9WjrQc5kbsyEojPDg6qmSyxI5q+iYIRj3YRgk+xpJNl" + + "0154SQCNvKPghJiw6aDFSifkytA01tp9/a8QWCwF433RjiFPsoekjvHQ6Y34dofO" + + "xDhf7lwJKPBFCrfYIqocklECgYAIPI9OHHGP8NKw94UJ0fX/WGug5sHVbQ9sWvOy" + + "KLMBlxLMxqFadlUaOpvVZvdxnX++ktajwpGxJDhX9OWWsYGobm1buB7N1E1Prrg+" + + "gt0RWpMhZa3Xeb/8Jorr2Lfo8sWK0LQyTE8hQCSIthfoWL9FeJJn/GKF/dSj8kxU" + + "0QIGMQKBgG/8U/zZ87DzfXS81P1p+CmH474wmou4KD2/zXp/lDR9+dlIUeijlIbU" + + "P6Y5xJvT33Y40giW9irShgDHjZgw0ap11K3b2HzLImdPEaBiENo735rpLs8WLK9H" + + "+yeRbiP2y9To7sTihm9Jrkctzp6sqFtKyye1+S21X1tMz8NGfXen"; + + private static final String PKCS1_PUB_STR = + // the BASE64 string between -----BEGIN RSA PUBLIC KEY----- + // and -----END RSA PUBLIC KEY----- + "MIIBCgKCAQEA0OIArlYES4X1XMTLDordtN/XIWFE1wvhl40RsHWM2n99+StpCCJC" + + "cUb5FJ2/kefj/XRwB6p5IMpIZrHZqC8XXzlX5fpiFaSu2xnk17oWUKoErW27Stm0" + + "98pU2RoUxWPKVl+42a8iVp8tijNElBNFALCGi0zXOhcTxMh0q1Wk0UhMJqamv5Yn" + + "CKmT4THwwGYn/KeK3M7Qa+o5MoVBHLbeT9LJgEmSluVzIh44Lh6weX0bw72P8X2p" + + "raOhbzg2B343MqS/rMLw6On+0i7ccEgp23vX9G5w85q4A5FSIrk4S/pyv5sOrwjC" + + "QKBW1TS0/2iB9zNkFMj5/+h7l2oqTT7sSQIDAQAB"; + + + private static final PrivateKey CUSTOM_PRIV; + private static final PublicKey CUSTOM_PUB; + + static { + byte[] encodedPriv = Base64.getDecoder().decode(PKCS1_PRIV_STR); + CUSTOM_PRIV = new PrivateKey() { + @Override + public String getAlgorithm() { + return "RSA"; + } + @Override + public String getFormat() { + return "PKCS#1"; + } + @Override + public byte[] getEncoded() { + // skip cloning for testing key. + return encodedPriv; + } + }; + byte[] encodedPub = Base64.getDecoder().decode(PKCS1_PUB_STR); + CUSTOM_PUB = new PublicKey() { + @Override + public String getAlgorithm() { + return "RSA"; + } + @Override + public String getFormat() { + return "PKCS#1"; + } + @Override + public byte[] getEncoded() { + // skip cloning for testing key. + return encodedPub; + } + }; + } + static KeyStore getKeyStore() throws Exception { KeyStore ks; try (InputStream in = new FileInputStream(new File(BASE, "rsakeys.ks"))) { @@ -68,44 +146,64 @@ throw new Exception("Format not PKCS#8"); } } - if (key1.equals(key2) == false) { - throw new Exception("Keys not equal"); + // skip equals check when key1 is custom key + if (key1 != CUSTOM_PRIV && key1 != CUSTOM_PUB) { + if (!key1.equals(key2)) { + throw new Exception("Keys not equal"); + } } - if (Arrays.equals(key1.getEncoded(), key2.getEncoded()) == false) { + // only compare encodings if keys are of the same format + if (key1.getFormat().equals(key2.getFormat()) && + !Arrays.equals(key1.getEncoded(), key2.getEncoded())) { throw new Exception("Encodings not equal"); } } - private static void testPublic(KeyFactory kf, PublicKey key) throws Exception { - System.out.println("Testing public key..."); + private static void testPublic(KeyFactory kf, PublicKey key) + throws Exception { + System.out.println("Testing " + (key == CUSTOM_PUB? "PKCS#1" : "") + + " public key..."); PublicKey key2 = (PublicKey)kf.translateKey(key); KeySpec rsaSpec = kf.getKeySpec(key, RSAPublicKeySpec.class); PublicKey key3 = kf.generatePublic(rsaSpec); KeySpec x509Spec = kf.getKeySpec(key, X509EncodedKeySpec.class); PublicKey key4 = kf.generatePublic(x509Spec); - KeySpec x509Spec2 = new X509EncodedKeySpec(key.getEncoded()); - PublicKey key5 = kf.generatePublic(x509Spec2); - testKey(key, key); + if (key != CUSTOM_PUB) { + testKey(key, key); + } testKey(key, key2); testKey(key, key3); testKey(key, key4); - testKey(key, key5); + + if (key.getFormat().equalsIgnoreCase("X.509")) { + KeySpec x509Spec2 = new X509EncodedKeySpec(key.getEncoded()); + PublicKey key5 = kf.generatePublic(x509Spec2); + testKey(key, key5); + } + } - private static void testPrivate(KeyFactory kf, PrivateKey key) throws Exception { - System.out.println("Testing private key..."); + private static void testPrivate(KeyFactory kf, PrivateKey key) + throws Exception { + System.out.println("Testing " + (key == CUSTOM_PRIV? "PKCS#1" : "") + + " private key..."); PrivateKey key2 = (PrivateKey)kf.translateKey(key); KeySpec rsaSpec = kf.getKeySpec(key, RSAPrivateCrtKeySpec.class); PrivateKey key3 = kf.generatePrivate(rsaSpec); KeySpec pkcs8Spec = kf.getKeySpec(key, PKCS8EncodedKeySpec.class); PrivateKey key4 = kf.generatePrivate(pkcs8Spec); - KeySpec pkcs8Spec2 = new PKCS8EncodedKeySpec(key.getEncoded()); - PrivateKey key5 = kf.generatePrivate(pkcs8Spec2); - testKey(key, key); + if (key != CUSTOM_PRIV) { + testKey(key, key); + } testKey(key, key2); testKey(key, key3); testKey(key, key4); - testKey(key, key5); + + if (key.getFormat().equalsIgnoreCase("PKCS#8")) { + KeySpec pkcs8Spec2 = new PKCS8EncodedKeySpec(key.getEncoded()); + PrivateKey key5 = kf.generatePrivate(pkcs8Spec2); + testKey(key, key5); + } // XXX PKCS#11 providers may not support non-CRT keys (e.g. NSS) // KeySpec rsaSpec2 = kf.getKeySpec(key, RSAPrivateKeySpec.class); @@ -145,6 +243,10 @@ test(kf, ks.getCertificate(alias).getPublicKey()); } } + // repeat the test w/ PKCS#1 RSA Private Key + test(kf, CUSTOM_PRIV); + test(kf, CUSTOM_PUB); + long stop = System.currentTimeMillis(); System.out.println("All tests passed (" + (stop - start) + " ms)."); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -23,7 +23,7 @@ /* * @test - * @bug 8076190 8153005 8266182 + * @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 * vice versa. diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs12/ParamsPreferences.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs12/ParamsPreferences.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs12/ParamsPreferences.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs12/ParamsPreferences.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -37,7 +37,7 @@ /* * @test - * @bug 8076190 8153005 8266293 + * @bug 8076190 8242151 8153005 8266293 * @library /test/lib * @modules java.base/sun.security.pkcs * java.base/sun.security.x509 diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/pkcs12/PKCS12SameKeyId.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6958026 + * @bug 6958026 8242151 * @summary Problem with PKCS12 keystore * @modules java.base/sun.security.pkcs * java.base/sun.security.tools.keytool @@ -75,7 +75,7 @@ AlgorithmParameters.getInstance("PBEWithSHA1AndDESede"); algParams.init(new PBEParameterSpec("12345678".getBytes(), 1024)); AlgorithmId algid = new AlgorithmId( - new ObjectIdentifier("1.2.840.113549.1.12.1.3"), algParams); + ObjectIdentifier.of("1.2.840.113549.1.12.1.3"), algParams); PBEKeySpec keySpec = new PBEKeySpec(PASSWORD); SecretKeyFactory skFac = SecretKeyFactory.getInstance("PBE"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/provider/SecureRandom/SHA1PRNGReseed.java openjdk-lts-11.0.21+9/test/jdk/sun/security/provider/SecureRandom/SHA1PRNGReseed.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/provider/SecureRandom/SHA1PRNGReseed.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/provider/SecureRandom/SHA1PRNGReseed.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -28,14 +28,14 @@ /** * @test - * @bug 8154523 + * @bug 8154523 8247895 * @summary SHA1PRNG output should change after setSeed */ public class SHA1PRNGReseed { public static void main(String[] args) throws Exception { SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); - sr.setSeed(0); + sr.setSeed(1); sr.nextInt(); ByteArrayOutputStream bout = new ByteArrayOutputStream(); @@ -45,7 +45,7 @@ new ByteArrayInputStream(bout.toByteArray())).readObject(); int i1 = sr.nextInt(); - sr2.setSeed(1); + sr2.setSeed(2); int i2 = sr2.nextInt(); if (i1 == i2) { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/rsa/TestKeyFactory.java openjdk-lts-11.0.21+9/test/jdk/sun/security/rsa/TestKeyFactory.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/rsa/TestKeyFactory.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/rsa/TestKeyFactory.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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,7 +23,7 @@ /** * @test - * @bug 4853305 8254717 + * @bug 4853305 8023980 8254717 * @summary Test KeyFactory of the new RSA provider * @author Andreas Sterbenz */ @@ -41,6 +41,84 @@ private static final char[] password = "test12".toCharArray(); + private static final String PKCS1_PRIV_STR = + // the BASE64 string between -----BEGIN RSA PRIVATE KEY----- + // and -----END RSA PRIVATE KEY----- + "MIIEowIBAAKCAQEA0OIArlYES4X1XMTLDordtN/XIWFE1wvhl40RsHWM2n99+Stp" + + "CCJCcUb5FJ2/kefj/XRwB6p5IMpIZrHZqC8XXzlX5fpiFaSu2xnk17oWUKoErW27" + + "Stm098pU2RoUxWPKVl+42a8iVp8tijNElBNFALCGi0zXOhcTxMh0q1Wk0UhMJqam" + + "v5YnCKmT4THwwGYn/KeK3M7Qa+o5MoVBHLbeT9LJgEmSluVzIh44Lh6weX0bw72P" + + "8X2praOhbzg2B343MqS/rMLw6On+0i7ccEgp23vX9G5w85q4A5FSIrk4S/pyv5sO" + + "rwjCQKBW1TS0/2iB9zNkFMj5/+h7l2oqTT7sSQIDAQABAoIBADn6sXOynoiUC1IP" + + "sck8lGOTSjSSujfyrVCSsJlJV6qCfuX9va6rS8QDjjnBu531PtxoSHxoPizy2Pvg" + + "W+kKATPGR/am9DjLuFlKq7GRjoYfWyMEdVtGaKvq9ng4fBF6LHyjHz0VFrPyhQJ6" + + "TovHeXzCguYBkzAlnbAeb/vqzs/kABbOuSHVi7DsaixCoEX9zOptFYQw/l8rh68+" + + "UF2bpNNH3jOC1uN3vZtuSwCupqtN+2Mpkx2h04Rk75vWIhrnPeMgmcd3yP4LNZMR" + + "mfaynb63RRzVkNis7+NVk016SQ1oL79mrBvy5rBg3HeCeArwvqZAmOaWsLSWHzCy" + + "zlVlMTECgYEA6JlnMpC956Qi8HX5ye4Hu2ovBdbNGtH/TMkZmColJz9P7CvNkNIb" + + "Od6mvLMydbPHkhdBUDWD4rhiCKHrf5zKju1i24YqWcvuSGotWj4/KQ3+87mLZM+7" + + "daBsJBmSEVB80sgA9ItqSgOyNoNFpiDgFnlszAfb0n9XXEzB/pwSw1UCgYEA5eXI" + + "d+eKugugP+n6CluQfyxfN6WWCzfqWToCTTxPn2i12AiEssXy+kyLjupJVLWSivdo" + + "83wD5LuxFRGc9P+aKQERPhb0AFaxf1llUCXla65/x2So5xjMvtuzgQ0OktPJqJXq" + + "hYGunctsr5rje33+7vlx4xWkrL2PrQWzJabn7SUCgYEAqw3FesY/Ik7u8u+P1xSZ" + + "0xXvptek1oiAu7NYgzLbR9WjrQc5kbsyEojPDg6qmSyxI5q+iYIRj3YRgk+xpJNl" + + "0154SQCNvKPghJiw6aDFSifkytA01tp9/a8QWCwF433RjiFPsoekjvHQ6Y34dofO" + + "xDhf7lwJKPBFCrfYIqocklECgYAIPI9OHHGP8NKw94UJ0fX/WGug5sHVbQ9sWvOy" + + "KLMBlxLMxqFadlUaOpvVZvdxnX++ktajwpGxJDhX9OWWsYGobm1buB7N1E1Prrg+" + + "gt0RWpMhZa3Xeb/8Jorr2Lfo8sWK0LQyTE8hQCSIthfoWL9FeJJn/GKF/dSj8kxU" + + "0QIGMQKBgG/8U/zZ87DzfXS81P1p+CmH474wmou4KD2/zXp/lDR9+dlIUeijlIbU" + + "P6Y5xJvT33Y40giW9irShgDHjZgw0ap11K3b2HzLImdPEaBiENo735rpLs8WLK9H" + + "+yeRbiP2y9To7sTihm9Jrkctzp6sqFtKyye1+S21X1tMz8NGfXen"; + + private static final String PKCS1_PUB_STR = + // the BASE64 string between -----BEGIN RSA PUBLIC KEY----- + // and -----END RSA PUBLIC KEY----- + "MIIBCgKCAQEA0OIArlYES4X1XMTLDordtN/XIWFE1wvhl40RsHWM2n99+StpCCJC" + + "cUb5FJ2/kefj/XRwB6p5IMpIZrHZqC8XXzlX5fpiFaSu2xnk17oWUKoErW27Stm0" + + "98pU2RoUxWPKVl+42a8iVp8tijNElBNFALCGi0zXOhcTxMh0q1Wk0UhMJqamv5Yn" + + "CKmT4THwwGYn/KeK3M7Qa+o5MoVBHLbeT9LJgEmSluVzIh44Lh6weX0bw72P8X2p" + + "raOhbzg2B343MqS/rMLw6On+0i7ccEgp23vX9G5w85q4A5FSIrk4S/pyv5sOrwjC" + + "QKBW1TS0/2iB9zNkFMj5/+h7l2oqTT7sSQIDAQAB"; + + + private static final PrivateKey P1_PRIV; + private static final PublicKey P1_PUB; + + static { + byte[] encodedPriv = Base64.getDecoder().decode(PKCS1_PRIV_STR); + P1_PRIV = new PrivateKey() { + @Override + public String getAlgorithm() { + return "RSA"; + } + @Override + public String getFormat() { + return "PKCS#1"; + } + @Override + public byte[] getEncoded() { + // skip cloning for testing key. + return encodedPriv; + } + }; + byte[] encodedPub = Base64.getDecoder().decode(PKCS1_PUB_STR); + P1_PUB = new PublicKey() { + @Override + public String getAlgorithm() { + return "RSA"; + } + @Override + public String getFormat() { + return "PKCS#1"; + } + @Override + public byte[] getEncoded() { + // skip cloning for testing key. + return encodedPub; + } + }; + } + static KeyStore getKeyStore() throws Exception { InputStream in = new FileInputStream(new File(BASE, "rsakeys.ks")); KeyStore ks = KeyStore.getInstance("JKS"); @@ -63,47 +141,67 @@ } } else if (key1 instanceof PrivateKey) { if (key2.getFormat().equals("PKCS#8") == false) { - throw new Exception("Format not PKCS#8"); + throw new Exception("Format not PKCS#8: " + key2.getFormat()); } } - if (key1.equals(key2) == false) { - throw new Exception("Keys not equal"); + // skip equals check when key1 is custom key + if (key1 != P1_PRIV && key1 != P1_PUB) { + if (!key1.equals(key2)) { + throw new Exception("Keys not equal"); + } } - if (Arrays.equals(key1.getEncoded(), key2.getEncoded()) == false) { + + // only compare encodings if keys are of the same format + if (key1.getFormat().equals(key2.getFormat()) && + !Arrays.equals(key1.getEncoded(), key2.getEncoded())) { throw new Exception("Encodings not equal"); } } - private static void testPublic(KeyFactory kf, PublicKey key) throws Exception { - System.out.println("Testing public key..."); + private static void testPublic(KeyFactory kf, PublicKey key) + throws Exception { + System.out.println("Testing " + (key == P1_PUB? "PKCS#1" : "") + + " public key..."); + PublicKey key2 = (PublicKey)kf.translateKey(key); KeySpec rsaSpec = kf.getKeySpec(key, RSAPublicKeySpec.class); PublicKey key3 = kf.generatePublic(rsaSpec); KeySpec x509Spec = kf.getKeySpec(key, X509EncodedKeySpec.class); PublicKey key4 = kf.generatePublic(x509Spec); - KeySpec x509Spec2 = new X509EncodedKeySpec(key.getEncoded()); - PublicKey key5 = kf.generatePublic(x509Spec2); - testKey(key, key); + if (key != P1_PUB) { + testKey(key, key); + } testKey(key, key2); testKey(key, key3); testKey(key, key4); - testKey(key, key5); + + if (key.getFormat().equalsIgnoreCase("X.509")) { + KeySpec x509Spec2 = new X509EncodedKeySpec(key.getEncoded()); + PublicKey key5 = kf.generatePublic(x509Spec2); + testKey(key, key5); + } } - private static void testPrivate(KeyFactory kf, PrivateKey key) throws Exception { - System.out.println("Testing private key..."); + private static void testPrivate(KeyFactory kf, PrivateKey key) + throws Exception { + System.out.println("Testing " + (key == P1_PRIV? "PKCS#1" : "") + + " private key..."); PrivateKey key2 = (PrivateKey)kf.translateKey(key); KeySpec rsaSpec = kf.getKeySpec(key, RSAPrivateCrtKeySpec.class); PrivateKey key3 = kf.generatePrivate(rsaSpec); KeySpec pkcs8Spec = kf.getKeySpec(key, PKCS8EncodedKeySpec.class); PrivateKey key4 = kf.generatePrivate(pkcs8Spec); - KeySpec pkcs8Spec2 = new PKCS8EncodedKeySpec(key.getEncoded()); - PrivateKey key5 = kf.generatePrivate(pkcs8Spec2); - testKey(key, key); + if (key != P1_PRIV) { + testKey(key, key); + } testKey(key, key2); testKey(key, key3); testKey(key, key4); - testKey(key, key5); + if (key.getFormat().equalsIgnoreCase("PKCS#8")) { + KeySpec pkcs8Spec2 = new PKCS8EncodedKeySpec(key.getEncoded()); + PrivateKey key5 = kf.generatePrivate(pkcs8Spec2); + testKey(key, key5); + } KeySpec rsaSpec2 = kf.getKeySpec(key, RSAPrivateKeySpec.class); PrivateKey key6 = kf.generatePrivate(rsaSpec2); @@ -141,6 +239,10 @@ test(kf, ks.getCertificate(alias).getPublicKey()); } } + // repeat the test w/ PKCS#1 RSA Private Key + test(kf, P1_PRIV); + test(kf, P1_PUB); + long stop = System.currentTimeMillis(); System.out.println("All tests passed (" + (stop - start) + " ms)."); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/rsa/TestRSAOidSupport.java openjdk-lts-11.0.21+9/test/jdk/sun/security/rsa/TestRSAOidSupport.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/rsa/TestRSAOidSupport.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/rsa/TestRSAOidSupport.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 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 + * @bug 8242897 + * @summary Ensure that RSA key factory can parse X.509 encodings containing + * non-standard RSA oid as in older JDK releases before JDK-8146293 + * @run main TestRSAOidSupport + */ + +import java.security.KeyFactory; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.X509EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; + +public class TestRSAOidSupport { + + // SubjectKeyInfo DER encoding w/ Algorithm id 1.3.14.3.2.15 + // which can be used to generate RSA Public Key before PSS + // support is added + private static String DER_BYTES = + "3058300906052b0e03020f0500034b003048024100d7157c65e8f22557d8" + + "a857122cfe85bddfaba3064c21b345e2a7cdd8a6751e519ab861c5109fb8" + + "8cce45d161b9817bc0eccdc30fda69e62cc577775f2c1d66bd0203010001"; + + // utility method for converting hex string to byte array + static byte[] toByteArray(String s) { + byte[] bytes = new byte[s.length() / 2]; + for (int i = 0; i < bytes.length; i++) { + int index = i * 2; + int v = Integer.parseInt(s.substring(index, index + 2), 16); + bytes[i] = (byte) v; + } + return bytes; + } + + public static void main(String[] args) throws Exception { + X509EncodedKeySpec x509Spec = new X509EncodedKeySpec + (toByteArray(DER_BYTES)); + String keyAlgo = "RSA"; + KeyFactory kf = KeyFactory.getInstance(keyAlgo, "SunRsaSign"); + RSAPublicKey rsaKey = (RSAPublicKey) kf.generatePublic(x509Spec); + + if (rsaKey.getAlgorithm() != keyAlgo) { + throw new RuntimeException("Key algo should be " + keyAlgo + + ", but got " + rsaKey.getAlgorithm()); + } + kf = KeyFactory.getInstance("RSASSA-PSS", "SunRsaSign"); + try { + kf.generatePublic(x509Spec); + throw new RuntimeException("Should throw IKSE"); + } catch (InvalidKeySpecException ikse) { + System.out.println("Expected IKSE exception thrown"); + } + } +} + diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/DHKeyExchange/DHEKeySizing.java openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/DHKeyExchange/DHEKeySizing.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/DHKeyExchange/DHEKeySizing.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/DHKeyExchange/DHEKeySizing.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, 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 @@ -28,7 +28,7 @@ /* * @test - * @bug 6956398 + * @bug 6956398 8301700 * @summary make ephemeral DH key match the length of the certificate key * @run main/othervm * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1643 267 @@ -48,7 +48,7 @@ * DHEKeySizing SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA true 233 75 * * @run main/othervm -Djsse.enableFFDHE=false - * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1387 139 + * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1643 267 * @run main/othervm -Djsse.enableFFDHE=false * -Djdk.tls.ephemeralDHKeySize=legacy * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1323 107 @@ -60,13 +60,13 @@ * DHEKeySizing TLS_DHE_RSA_WITH_AES_128_CBC_SHA false 1387 139 * * @run main/othervm -Djsse.enableFFDHE=false - * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 361 139 + * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 617 267 * @run main/othervm -Djsse.enableFFDHE=false * -Djdk.tls.ephemeralDHKeySize=legacy * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 297 107 * @run main/othervm -Djsse.enableFFDHE=false * -Djdk.tls.ephemeralDHKeySize=matched - * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 361 139 + * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 617 267 * @run main/othervm -Djsse.enableFFDHE=false * -Djdk.tls.ephemeralDHKeySize=1024 * DHEKeySizing SSL_DH_anon_WITH_RC4_128_MD5 false 361 139 @@ -93,7 +93,7 @@ * } dh_public; * } ClientDiffieHellmanPublic; * - * Fomr above structures, it is clear that if the DH key size increasing 128 + * From the above structures, it is clear that if the DH key size increases 128 * bits (16 bytes), the ServerHello series messages increases 48 bytes * (becuase dh_p, dh_g and dh_Ys each increase 16 bytes) and ClientKeyExchange * increases 16 bytes (because of the size increasing of dh_Yc). @@ -104,7 +104,7 @@ * 512-bit | 1259 bytes | 75 bytes | 233 bytes * 768-bit | 1323 bytes | 107 bytes | 297 bytes * 1024-bit | 1387 bytes | 139 bytes | 361 bytes - * 2048-bit | 1643 bytes | 267 bytes | 361 bytes + * 2048-bit | 1643 bytes | 267 bytes | 617 bytes */ import javax.net.ssl.*; diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/SSLContextImpl/DefaultCipherSuitePreference.java openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/SSLContextImpl/DefaultCipherSuitePreference.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/SSLContextImpl/DefaultCipherSuitePreference.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/SSLContextImpl/DefaultCipherSuitePreference.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 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. + */ + +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + +/* + * @test + * @bug 8168261 + * @summary Use server cipher suites preference by default + * @run main/othervm DefaultCipherSuitePreference + */ + +import javax.net.SocketFactory; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; + +public class DefaultCipherSuitePreference { + private static final String[] contextAlgorithms = { + "Default", "SSL", "TLS", "SSLv3", "TLSv1", + "TLSv1.1", "TLSv1.2", "TLSv1.3" + }; + + public static void main(String[] args) throws Exception { + for (String algorithm : contextAlgorithms) { + System.out.println("Checking SSLContext of " + algorithm); + SSLContext sslContext = SSLContext.getInstance(algorithm); + + // Default SSLContext is initialized automatically. + if (!algorithm.equals("Default")) { + // Use default TK, KM and random. + sslContext.init((KeyManager[])null, (TrustManager[])null, null); + } + + // + // Check SSLContext + // + // Check default SSLParameters of SSLContext + checkDefaultCipherSuitePreference( + sslContext.getDefaultSSLParameters(), + "SSLContext.getDefaultSSLParameters()"); + + // Check supported SSLParameters of SSLContext + checkDefaultCipherSuitePreference( + sslContext.getSupportedSSLParameters(), + "SSLContext.getSupportedSSLParameters()"); + + // + // Check SSLEngine + // + // Check SSLParameters of SSLEngine + SSLEngine engine = sslContext.createSSLEngine(); + engine.setUseClientMode(true); + checkDefaultCipherSuitePreference( + engine.getSSLParameters(), + "client mode SSLEngine.getSSLParameters()"); + + engine.setUseClientMode(false); + checkDefaultCipherSuitePreference( + engine.getSSLParameters(), + "server mode SSLEngine.getSSLParameters()"); + + // + // Check SSLSocket + // + // Check SSLParameters of SSLSocket + SocketFactory fac = sslContext.getSocketFactory(); + SSLSocket socket = (SSLSocket)fac.createSocket(); + checkDefaultCipherSuitePreference( + socket.getSSLParameters(), + "SSLSocket.getSSLParameters()"); + + // + // Check SSLServerSocket + // + // Check SSLParameters of SSLServerSocket + SSLServerSocketFactory sf = sslContext.getServerSocketFactory(); + SSLServerSocket ssocket = (SSLServerSocket)sf.createServerSocket(); + checkDefaultCipherSuitePreference( + ssocket.getSSLParameters(), + "SSLServerSocket.getSSLParameters()"); + } + } + + private static void checkDefaultCipherSuitePreference( + SSLParameters parameters, String context) throws Exception { + if (!parameters.getUseCipherSuitesOrder()) { + throw new Exception( + "The local cipher suite preference is not honored " + + "in the connection populated SSLParameters object (" + + context + ")"); + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java 2023-10-06 05:33:33.000000000 +0000 @@ -126,7 +126,7 @@ System.out.println("test.java.opts: " + System.getProperty("test.java.opts")); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( Utils.addTestJavaOpts("SSLEngineKeyLimit", "p", args[1], args[2])); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketKeyLimit.java 2023-10-06 05:33:33.000000000 +0000 @@ -134,7 +134,7 @@ System.out.println("test.java.opts: " + System.getProperty("test.java.opts")); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, + ProcessBuilder pb = ProcessTools.createTestJvm( Utils.addTestJavaOpts("SSLSocketKeyLimit", "p", args[1], args[2])); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java 2023-10-06 05:33:33.000000000 +0000 @@ -35,6 +35,8 @@ * @run main/manual/othervm Compatibility */ +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; @@ -43,12 +45,12 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import java.nio.file.Path; import java.nio.file.Files; +import java.nio.file.Path; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -57,19 +59,18 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Function; -import java.util.jar.Manifest; import java.util.jar.Attributes.Name; -import java.util.concurrent.TimeUnit; +import java.util.jar.Manifest; import java.util.stream.Collectors; import java.util.stream.IntStream; + import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; -import static java.nio.charset.StandardCharsets.UTF_8; - public class Compatibility { private static final String TEST_SRC = System.getProperty("test.src"); @@ -179,7 +180,7 @@ List signItems = test(jdkInfoList, tsaList, certList, createJars()); - boolean failed = generateReport(tsaList, signItems); + boolean failed = generateReport(jdkInfoList, tsaList, signItems); // Restores the original stdout and stderr. System.setOut(origStdOut); @@ -415,11 +416,15 @@ } List jdkInfoList = new ArrayList<>(); + int index = 0; for (String jdkPath : jdkList) { JdkInfo jdkInfo = "TEST_JDK".equalsIgnoreCase(jdkPath) ? TEST_JDK_INFO : new JdkInfo(jdkPath); // The JDK version must be unique. if (!jdkInfoList.contains(jdkInfo)) { + jdkInfo.index = index++; + jdkInfo.version = String.format( + "%s(%d)", jdkInfo.version, jdkInfo.index); jdkInfoList.add(jdkInfo); } else { System.out.println("The JDK version is duplicate: " + jdkPath); @@ -908,13 +913,22 @@ } // Generates the test result report. - private static boolean generateReport(List tsaList, + private static boolean generateReport(List jdkList, List tsaList, List signItems) throws IOException { System.out.println("Report is being generated..."); StringBuilder report = new StringBuilder(); report.append(HtmlHelper.startHtml()); report.append(HtmlHelper.startPre()); + + // Generates JDK list + report.append("JDK list:\n"); + for(JdkInfo jdkInfo : jdkList) { + report.append(String.format("%d=%s%n", + jdkInfo.index, + jdkInfo.runtimeVersion)); + } + // Generates TSA URLs report.append("TSA list:\n"); for(TsaInfo tsaInfo : tsaList) { @@ -1024,9 +1038,11 @@ private static class JdkInfo { + private int index; private final String jdkPath; private final String jarsignerPath; - private final String version; + private final String runtimeVersion; + private String version; private final int majorVersion; private final boolean supportsTsadigestalg; @@ -1034,14 +1050,15 @@ private JdkInfo(String jdkPath) throws Throwable { this.jdkPath = jdkPath; - version = execJdkUtils(jdkPath, JdkUtils.M_JAVA_RUNTIME_VERSION); - if (version == null || version.isBlank()) { + jarsignerPath = jarsignerPath(jdkPath); + runtimeVersion = execJdkUtils(jdkPath, JdkUtils.M_JAVA_RUNTIME_VERSION); + if (runtimeVersion == null || runtimeVersion.isBlank()) { throw new RuntimeException( "Cannot determine the JDK version: " + jdkPath); } - majorVersion = Integer.parseInt((version.matches("^1[.].*") ? - version.substring(2) : version).replaceAll("[^0-9].*$", "")); - jarsignerPath = jarsignerPath(jdkPath); + version = execJdkUtils(jdkPath, JdkUtils.M_JAVA_VERSION); + majorVersion = Integer.parseInt((runtimeVersion.matches("^1[.].*") ? + runtimeVersion.substring(2) : runtimeVersion).replaceAll("[^0-9].*$", "")); supportsTsadigestalg = execTool(jarsignerPath, "-help") .getOutput().contains("-tsadigestalg"); } @@ -1073,7 +1090,7 @@ final int prime = 31; int result = 1; result = prime * result - + ((version == null) ? 0 : version.hashCode()); + + ((runtimeVersion == null) ? 0 : runtimeVersion.hashCode()); return result; } @@ -1086,17 +1103,17 @@ if (getClass() != obj.getClass()) return false; JdkInfo other = (JdkInfo) obj; - if (version == null) { - if (other.version != null) + if (runtimeVersion == null) { + if (other.runtimeVersion != null) return false; - } else if (!version.equals(other.version)) + } else if (!runtimeVersion.equals(other.runtimeVersion)) return false; return true; } @Override public String toString() { - return "JdkInfo[" + version + ", " + jdkPath + "]"; + return "JdkInfo[" + runtimeVersion + ", " + jdkPath + "]"; } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/compatibility/JdkUtils.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/compatibility/JdkUtils.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/compatibility/JdkUtils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/compatibility/JdkUtils.java 2023-10-06 05:33:33.000000000 +0000 @@ -36,12 +36,18 @@ KEY, SIG, DIGEST; } + static final String M_JAVA_VERSION = "javaVersion"; static final String M_JAVA_RUNTIME_VERSION = "javaRuntimeVersion"; static final String M_IS_SUPPORTED_KEYALG = "isSupportedKeyalg"; static final String M_IS_SUPPORTED_SIGALG = "isSupportedSigalg"; static final String M_IS_SUPPORTED_DIGESTALG = "isSupportedDigestalg"; // Returns the JDK build version. + static String javaVersion() { + return System.getProperty("java.version"); + } + + // Returns the JDK build runtime version. static String javaRuntimeVersion() { return System.getProperty("java.runtime.version"); } @@ -63,7 +69,9 @@ } public static void main(String[] args) { - if (M_JAVA_RUNTIME_VERSION.equals(args[0])) { + if (M_JAVA_VERSION.equals(args[0])) { + System.out.print(javaVersion()); + } else if (M_JAVA_RUNTIME_VERSION.equals(args[0])) { System.out.print(javaRuntimeVersion()); } else if (M_IS_SUPPORTED_KEYALG.equals(args[0])) { System.out.print(isSupportedAlg(Alg.KEY, args[1])); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/compatibility/SignTwice.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/compatibility/SignTwice.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/compatibility/SignTwice.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/compatibility/SignTwice.java 2023-10-06 05:33:33.000000000 +0000 @@ -36,7 +36,7 @@ * @test * @library /test/lib ../warnings * @compile Compatibility.java - * @run main/othervm/timeout=2500 + * @run main/othervm/timeout=600 * -Djava.security.properties=./java.security * -Duser.language=en * -Duser.country=US @@ -46,8 +46,8 @@ * -DtestComprehensiveJarContents=true * -DtestJarUpdate=true * -Dstrict=true - * -DkeyAlgs=EC;#RSA;#DSA; - * -DdigestAlgs=SHA-512 + * -DkeyAlgs=EC;0 + * -DdigestAlgs=SHA-256 * SignTwice */ public class SignTwice { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/warnings/NoTimestampTest.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/warnings/NoTimestampTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/warnings/NoTimestampTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/warnings/NoTimestampTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,6 +27,7 @@ import java.security.cert.X509Certificate; import java.util.Date; import java.util.Locale; +import java.util.TimeZone; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.util.JarUtils; @@ -46,6 +47,7 @@ * and checks that proper warnings are shown. */ public static void main(String[] args) throws Throwable { + Locale reservedLocale = Locale.getDefault(); Locale.setDefault(Locale.US); @@ -61,6 +63,9 @@ private void start() throws Throwable { String timezone = System.getProperty("user.timezone"); System.out.println(String.format("Timezone = %s", timezone)); + if (timezone != null) { + TimeZone.setDefault(TimeZone.getTimeZone(timezone)); + } // create a jar file that contains one class file Utils.createFiles(FIRST_FILE); @@ -73,10 +78,11 @@ "-validity", Integer.toString(VALIDITY)); Date expirationDate = getCertExpirationDate(); + System.out.println("Cert expiration: " + expirationDate); // sign jar file OutputAnalyzer analyzer = jarsigner( - "-J-Duser.timezone=" + timezone, + userTimezoneOpt(timezone), "-keystore", KEYSTORE, "-storepass", PASSWORD, "-keypass", PASSWORD, @@ -90,7 +96,7 @@ // verify signed jar analyzer = jarsigner( - "-J-Duser.timezone=" + timezone, + userTimezoneOpt(timezone), "-verify", "-keystore", KEYSTORE, "-storepass", PASSWORD, @@ -103,7 +109,7 @@ // verify signed jar in strict mode analyzer = jarsigner( - "-J-Duser.timezone=" + timezone, + userTimezoneOpt(timezone), "-verify", "-strict", "-keystore", KEYSTORE, @@ -117,6 +123,10 @@ System.out.println("Test passed"); } + private static String userTimezoneOpt(String timezone) { + return timezone == null ? null : "-J-Duser.timezone=" + timezone; + } + private static Date getCertExpirationDate() throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); try (InputStream in = new FileInputStream(KEYSTORE)) { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/warnings/Test.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/warnings/Test.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/jarsigner/warnings/Test.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/jarsigner/warnings/Test.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -21,12 +21,13 @@ * questions. */ -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; /** * Base class. @@ -263,7 +264,9 @@ cmd.add(tool); cmd.add("-J-Duser.language=en"); cmd.add("-J-Duser.country=US"); - cmd.addAll(Arrays.asList(args)); + cmd.addAll(Arrays.asList(args).stream().filter(arg -> { + return arg != null && !arg.isEmpty(); + }).collect(Collectors.toList())); return ProcessTools.executeCommand(cmd.toArray(new String[cmd.size()])); } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/rsa/RSAKeyPairGenerator.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/rsa/RSAKeyPairGenerator.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/rsa/RSAKeyPairGenerator.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/keytool/fakegen/java.base/sun/security/rsa/RSAKeyPairGenerator.java 2023-10-06 05:33:33.000000000 +0000 @@ -29,8 +29,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; -import sun.security.x509.AlgorithmId; -import static sun.security.rsa.RSAUtil.KeyType; +import sun.security.rsa.RSAUtil.KeyType; /** * A fake RSA keypair generation. @@ -44,7 +43,7 @@ private int keySize; private final KeyType type; - private AlgorithmId rsaId; + private AlgorithmParameterSpec keyParams; RSAKeyPairGenerator(KeyType type, int defKeySize) { this.type = type; @@ -98,7 +97,7 @@ } try { - this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams); + this.keyParams = RSAUtil.checkParamsAgainstType(type, tmpParams); } catch (ProviderException e) { throw new InvalidAlgorithmParameterException( "Invalid key parameters", e); @@ -536,9 +535,9 @@ BigInteger coeff = q.modInverse(p); try { - PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e); + PublicKey publicKey = new RSAPublicKeyImpl(type, keyParams, n, e); PrivateKey privateKey = new RSAPrivateCrtKeyImpl( - rsaId, n, e, d, p, q, pe, qe, coeff); + type, keyParams, n, e, d, p, q, pe, qe, coeff); return new KeyPair(publicKey, privateKey); } catch (InvalidKeyException exc) { // invalid key exception only thrown for keys < 512 bit, diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/keytool/KeyToolTest.java openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/keytool/KeyToolTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/tools/keytool/KeyToolTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/tools/keytool/KeyToolTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -24,6 +24,7 @@ /* * @test * @author weijun.wang + * @bug 8242151 * @summary Testing keytool * * Run through autotest.sh and manualtest.sh @@ -1599,7 +1600,7 @@ int pos = 0; System.err.print("x"); Extension ex = ((X509CertImpl)ks.getCertificate(alias)) - .getExtension(new ObjectIdentifier(oid)); + .getExtension(ObjectIdentifier.of(oid)); if (!Arrays.equals(value, ex.getValue())) { throw new RuntimeException("Not same content in " + alias + " for " + oid); @@ -1608,9 +1609,9 @@ } CheckOid coid = new CheckOid(); assertTrue(((X509CertImpl)ks.getCertificate("oid1")) - .getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + .getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); assertTrue(!((X509CertImpl)ks.getCertificate("oid2")) - .getExtension(new ObjectIdentifier("1.2.3")).isCritical()); + .getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); coid.check(ks, "oid1", "1.2.3", new byte[]{1,2}); coid.check(ks, "oid2", "1.2.3", new byte[]{}); coid.check(ks, "oid12", "1.2.3", new byte[]{}); @@ -1640,14 +1641,14 @@ assertTrue(a.getAuthorityKeyIdentifierExtension() != null); assertTrue(a.getSubjectKeyIdentifierExtension() != null); assertTrue(a.getKeyUsage() == null); - assertTrue(a.getExtension(new ObjectIdentifier("1.2.3")).isCritical()); - assertTrue(!a.getExtension(new ObjectIdentifier("1.2.4")).isCritical()); - assertTrue(!a.getExtension(new ObjectIdentifier("1.2.5")).isCritical()); + assertTrue(a.getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); + assertTrue(!a.getExtension(ObjectIdentifier.of("1.2.4")).isCritical()); + assertTrue(!a.getExtension(ObjectIdentifier.of("1.2.5")).isCritical()); assertTrue(a.getExtensionValue("1.2.3").length == 3); assertTrue(a.getExtensionValue("1.2.4").length == 4); assertTrue(a.getExtensionValue("1.2.5").length == 5); assertTrue(a.getBasicConstraints() == 2); - assertTrue(!a.getExtension(new ObjectIdentifier("2.3.4")).isCritical()); + assertTrue(!a.getExtension(ObjectIdentifier.of("2.3.4")).isCritical()); assertTrue(a.getExtensionValue("2.3.4").length == 6); // 8073181: keytool -ext honored not working correctly @@ -1657,8 +1658,8 @@ testOK("", simple+"-importcert -file test2.cert -alias b"); ks = loadStore("x.jks", "changeit", "JKS"); X509CertImpl b = (X509CertImpl)ks.getCertificate("b"); - assertTrue(!b.getExtension(new ObjectIdentifier("1.2.3")).isCritical()); - assertTrue(b.getExtension(new ObjectIdentifier("1.2.4")).isCritical()); + assertTrue(!b.getExtension(ObjectIdentifier.of("1.2.3")).isCritical()); + assertTrue(b.getExtension(ObjectIdentifier.of("1.2.4")).isCritical()); // 8073182: keytool may generate duplicate extensions testOK("", pre+"dup -ext bc=2 -ext 2.5.29.19=30030101FF -ext bc=3"); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/Oid/OidEquals.java openjdk-lts-11.0.21+9/test/jdk/sun/security/util/Oid/OidEquals.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/Oid/OidEquals.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/util/Oid/OidEquals.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8022444 + * @bug 8022444 8242151 * @summary Test ObjectIdentifier.equals(Object obj) * @modules java.base/sun.security.util */ @@ -32,14 +32,11 @@ public class OidEquals { public static void main(String[] args) throws Exception { - ObjectIdentifier oid1 = new ObjectIdentifier("1.3.6.1.4.1.42.2.17"); - ObjectIdentifier oid2 = - new ObjectIdentifier(new int[]{1, 3, 6, 1, 4, 1, 42, 2, 17}); - ObjectIdentifier oid3 = new ObjectIdentifier("1.2.3.4"); + ObjectIdentifier oid1 = ObjectIdentifier.of("1.3.6.1.4.1.42.2.17"); + ObjectIdentifier oid2 = ObjectIdentifier.of("1.2.3.4"); assertEquals(oid1, oid1); - assertEquals(oid1, oid2); - assertNotEquals(oid1, oid3); + assertNotEquals(oid1, oid2); assertNotEquals(oid1, "1.3.6.1.4.1.42.2.17"); System.out.println("Tests passed."); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/Oid/OidFormat.java openjdk-lts-11.0.21+9/test/jdk/sun/security/util/Oid/OidFormat.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/Oid/OidFormat.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/util/Oid/OidFormat.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 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 @@ -24,9 +24,7 @@ /* * @test * @author Weijun Wang - * @bug 6418422 - * @bug 6418425 - * @bug 6418433 + * @bug 6418422 6418425 6418433 8242151 * @summary ObjectIdentifier should reject 1.2.3.-4 and throw IOException on all format errors * @modules java.base/sun.security.util * java.security.jgss @@ -86,57 +84,11 @@ for (String s: goodOids) { testGood(s); } - - int[][] goodInts = { - {0,0}, {0,1}, {1,0}, {1,2}, - {0,39}, {1,39}, {2,47}, {2,40,3,6}, {2,100,3}, {2,123456,3}, - {1,2,3}, {1,2,3445}, - {1,3,6,1,4,1,42,2,17}, - }; - - for (int[] is: goodInts) { - testGood(is); - } - - int[][] badInts = new int[][] { - {0}, {1}, {2}, - {3,1,1}, {3}, {4}, - {1,40}, {1,111,1}, - {-1,2}, {0,-2}, {1,-2}, {2,-2}, - {1,2,-3,4}, {1,2,3,-4}, - }; - - for (int[] is: badInts) { - testBad(is); - } - - } - - static void testBad(int[] ints) throws Exception { - System.err.println("Trying " + Arrays.toString(ints)); - try { - new ObjectIdentifier(ints); - throw new Exception("should be invalid ObjectIdentifier"); - } catch (IOException ioe) { - System.err.println(ioe); - } - } - - static void testGood(int[] ints) throws Exception { - System.err.println("Trying " + Arrays.toString(ints)); - ObjectIdentifier oid = new ObjectIdentifier(ints); - DerOutputStream os = new DerOutputStream(); - os.putOID(oid); - DerInputStream is = new DerInputStream(os.toByteArray()); - ObjectIdentifier oid2 = is.getOID(); - if (!oid.equals(oid2)) { - throw new Exception("Test DER I/O fails: " + oid + " and " + oid2); - } } static void testGood(String s) throws Exception { System.err.println("Trying " + s); - ObjectIdentifier oid = new ObjectIdentifier(s); + ObjectIdentifier oid = ObjectIdentifier.of(s); if (!oid.toString().equals(s)) { throw new Exception("equal test fail"); } @@ -152,7 +104,7 @@ static void testBad(String s) throws Exception { System.err.println("Trying " + s); try { - new ObjectIdentifier(s); + ObjectIdentifier.of(s); throw new Exception("should be invalid ObjectIdentifier"); } catch (IOException ioe) { System.err.println(ioe); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/Oid/S11N.java openjdk-lts-11.0.21+9/test/jdk/sun/security/util/Oid/S11N.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/Oid/S11N.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/util/Oid/S11N.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4811968 6908628 8006564 8130696 + * @bug 4811968 6908628 8006564 8130696 8242151 * @modules java.base/sun.security.util * @run main S11N check * @summary Serialization compatibility with old versions (and fixes) @@ -118,7 +118,7 @@ // Gets the serialized form for this java private static byte[] out(String oid) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); - new ObjectOutputStream(bout).writeObject(new ObjectIdentifier(oid)); + new ObjectOutputStream(bout).writeObject(ObjectIdentifier.of(oid)); return bout.toByteArray(); } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java openjdk-lts-11.0.21+9/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/util/RegisteredDomain/ParseNames.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * 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 8228969 8244087 8255266 + * @bug 8228969 8244087 8255266 8302182 * @modules java.base/sun.security.util * @summary unit test for RegisteredDomain */ diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/RegisteredDomain/tests.dat openjdk-lts-11.0.21+9/test/jdk/sun/security/util/RegisteredDomain/tests.dat --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/util/RegisteredDomain/tests.dat 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/util/RegisteredDomain/tests.dat 2023-10-06 05:33:33.000000000 +0000 @@ -84,6 +84,10 @@ www.foo.ie ie foo.ie www.foo.gov.ie gov.ie foo.gov.ie +# in +5g.in 5g.in null +www.5g.in 5g.in www.5g.in + # it has a large number of entries www.gr.it gr.it www.gr.it www.blahblahblah.it it blahblahblah.it @@ -153,4 +157,8 @@ foo.السعودية السعودية foo.السعودية w.foo.السعودية السعودية foo.السعودية +# Microsoft +1.azurestaticapps.net 1.azurestaticapps.net null +app.1.azurestaticapps.net 1.azurestaticapps.net app.1.azurestaticapps.net + ## END diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -23,8 +23,9 @@ /* * @test - * @bug 4162868 8130181 + * @bug 4162868 8130181 8242151 * @modules java.base/sun.security.x509 + * @modules java.base/sun.security.util * @run main/othervm ExtensibleAlgorithmId * @summary Algorithm Name-to-OID mapping needs to be made extensible. */ @@ -39,31 +40,43 @@ public static void main(String[] args) throws Exception { TestProvider p = new TestProvider(); Security.addProvider(p); - AlgorithmId algid = AlgorithmId.getAlgorithmId("XYZ"); - String alias = "Alg.Alias.Signature.OID." + algid.toString(); + AlgorithmId algid = AlgorithmId.getAlgorithmId(TestProvider.ALG_NAME); + String oid = algid.getOID().toString(); + if (!oid.equals(TestProvider.ALG_OID)) { + throw new Exception("Provider alias oid not used, found " + oid); + } + String name = algid.getName(); + if (!name.equalsIgnoreCase(TestProvider.ALG_NAME)) { + throw new Exception("provider alias name not used, found " + name); + } + String alias = "Alg.Alias.Signature.OID." + oid; String stdAlgName = p.getProperty(alias); - if (stdAlgName == null || !stdAlgName.equalsIgnoreCase("XYZ")) { + if (stdAlgName == null || + !stdAlgName.equalsIgnoreCase(TestProvider.ALG_NAME)) { throw new Exception("Wrong OID"); } } -} -class TestProvider extends Provider { + static class TestProvider extends Provider { - public TestProvider() { + static String ALG_OID = "1.2.3.4.5.6.7.8.9.0"; + static String ALG_NAME = "XYZ"; + + public TestProvider() { super("Dummy", "1.0", "XYZ algorithm"); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { - put("Signature.XYZ", "test.xyz"); - // preferred OID - put("Alg.Alias.Signature.OID.1.2.3.4.5.6.7.8.9.0", - "XYZ"); - put("Alg.Alias.Signature.9.8.7.6.5.4.3.2.1.0", - "XYZ"); - return null; - } - }); + put("Signature." + ALG_NAME, "test.xyz"); + // preferred OID + put("Alg.Alias.Signature.OID." + ALG_OID, + ALG_NAME); + put("Alg.Alias.Signature.9.8.7.6.5.4.3.2.1.0", + ALG_NAME); + return null; + } + }); + } } } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/AVA/AVAEqualsHashCode.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -24,7 +24,7 @@ /* * @test * @author Gary Ellison - * @bug 4170635 + * @bug 4170635 8242151 * @summary Verify equals()/hashCode() contract honored * @modules java.base/sun.security.util * java.base/sun.security.x509 @@ -40,13 +40,11 @@ public static void main(String[] args) throws Exception { - int data[] = { 1, 2, 840, 113549, 2, 5 }; - // encode String name = "CN=eve s. dropper"; X500Name dn = new X500Name(name); DerOutputStream deros = new DerOutputStream(); - ObjectIdentifier oid = new ObjectIdentifier(data); + ObjectIdentifier oid = ObjectIdentifier.of("1.2.840.113549.2.5"); dn.encode(deros); byte[] ba = deros.toByteArray(); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/equalNames/AltNamesEqualsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -24,7 +24,7 @@ /* * @test * @summary Make sure names that are equal are treated as such. - * @bug 4273559 + * @bug 4273559 8242151 * @author Yassir Elley * @modules java.base/sun.security.util * java.base/sun.security.x509 @@ -114,7 +114,7 @@ throws Exception { OIDName oidName = null; - ObjectIdentifier oid = new ObjectIdentifier(name); + ObjectIdentifier oid = ObjectIdentifier.of(name); oidName = new OIDName(oid); return oidName; } diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java --- openjdk-lts-11.0.20.1+1/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/sun/security/x509/X509CertImpl/V3Certificate.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8049237 + * @bug 8049237 8242151 * @modules java.base/sun.security.x509 * java.base/sun.security.util * jdk.crypto.ec @@ -153,9 +153,9 @@ GeneralNameInterface ipInf = new IPAddressName(address); GeneralName ip = new GeneralName(ipInf); - int[] oidData = new int[]{1, 2, 3, 4}; - GeneralNameInterface oidInf = new OIDName(new ObjectIdentifier(oidData)); + GeneralNameInterface oidInf = + new OIDName(ObjectIdentifier.of("1.2.3.4")); GeneralName oid = new GeneralName(oidInf); SubjectAlternativeNameExtension subjectName diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/jmod/hashes/HashesTest.java openjdk-lts-11.0.21+9/test/jdk/tools/jmod/hashes/HashesTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/jmod/hashes/HashesTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/jmod/hashes/HashesTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -368,6 +368,26 @@ }); } + @Test + public void upgradeableModule() throws IOException { + Path mpath = Paths.get(System.getProperty("java.home"), "jmods"); + if (!Files.exists(mpath)) { + return; + } + + makeModule("m1"); + makeModule("java.compiler", "m1"); + makeModule("m2", "java.compiler"); + + makeJmod("m1"); + makeJmod("m2"); + makeJmod("java.compiler", + "--module-path", + lib.toString() + File.pathSeparator + mpath, + "--hash-modules", "java\\.(?!se)|^m.*"); + + checkHashes("java.compiler", Set.of("m2")); + } private void makeModule(String mn, String... deps) throws IOException { makeModule(mn, null, deps); diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/AddExportsTest.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/AddExportsTest.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/AddExportsTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/AddExportsTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -24,7 +24,8 @@ /** * @test * @library /test/lib - * @modules jdk.compiler + * @modules java.compiler + * jdk.compiler * @build AddExportsTest jdk.test.lib.compiler.CompilerUtils * @run testng AddExportsTest * @summary Basic tests for java --add-exports @@ -51,12 +52,15 @@ private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); private static final Path MODS_DIR = Paths.get("mods"); + private static final Path UPGRADE_MODS_DIRS = Paths.get("upgrademods"); // test module m1 that uses Unsafe private static final String TEST1_MODULE = "m1"; private static final String TEST1_MAIN_CLASS = "jdk.test1.Main"; - + // test module m2 uses java.compiler internals + private static final String TEST2_MODULE = "m2"; + private static final String TEST2_MAIN_CLASS = "jdk.test2.Main"; // test module m3 uses m4 internals private static final String TEST3_MODULE = "m3"; @@ -74,7 +78,19 @@ "--add-exports", "java.base/jdk.internal.misc=m1"); assertTrue(compiled, "module " + TEST1_MODULE + " did not compile"); + // javac -d upgrademods/java.compiler src/java.compiler/** + compiled = CompilerUtils.compile( + SRC_DIR.resolve("java.compiler"), + UPGRADE_MODS_DIRS.resolve("java.compiler")); + assertTrue(compiled, "module java.compiler did not compile"); + // javac --upgrade-module-path upgrademods -d mods/m2 src/m2/** + compiled = CompilerUtils.compile( + SRC_DIR.resolve(TEST2_MODULE), + MODS_DIR.resolve(TEST2_MODULE), + "--upgrade-module-path", UPGRADE_MODS_DIRS.toString(), + "--add-exports", "java.compiler/javax.tools.internal=m2"); + assertTrue(compiled, "module " + TEST2_MODULE + " did not compile"); // javac -d mods/m3 src/m3/** compiled = CompilerUtils.compile( @@ -146,7 +162,25 @@ assertTrue(exitValue == 0); } + /** + * Test --add-exports with upgraded module + */ + public void testWithUpgradedModule() throws Exception { + // java --add-exports java.compiler/javax.tools.internal=m2 + // --upgrade-module-path upgrademods --module-path mods -m ... + String mid = TEST2_MODULE + "/" + TEST2_MAIN_CLASS; + int exitValue = executeTestJava( + "--add-exports", "java.compiler/javax.tools.internal=m2", + "--upgrade-module-path", UPGRADE_MODS_DIRS.toString(), + "--module-path", MODS_DIR.toString(), + "-m", mid) + .outputTo(System.out) + .errorTo(System.out) + .getExitValue(); + + assertTrue(exitValue == 0); + } /** * Test --add-exports with module that is added to the set of root modules diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/annotation/processing/Generated.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/annotation/processing/Generated.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/annotation/processing/Generated.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/annotation/processing/Generated.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 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. 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 javax.annotation.processing; + +public interface Generated { + + +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/internal/Helper.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/internal/Helper.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/internal/Helper.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/internal/Helper.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 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 javax.tools.internal; + +public class Helper { +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/ToolsHelper.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/ToolsHelper.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/ToolsHelper.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/javax/tools/ToolsHelper.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 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 javax.tools; + +public class ToolsHelper { +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/module-info.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/module-info.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/java.compiler/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/java.compiler/module-info.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 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. + */ + +module java.compiler { + exports javax.tools; + exports javax.annotation.processing; +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/m2/jdk/test2/Main.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/m2/jdk/test2/Main.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/m2/jdk/test2/Main.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/m2/jdk/test2/Main.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2015, 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 jdk.test2; + +import javax.tools.internal.Helper; + +public class Main { + public static void main(String[] args) { + Helper h = new Helper(); + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/m2/module-info.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/m2/module-info.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/modules/addexports/src/m2/module-info.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/modules/addexports/src/m2/module-info.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015, 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. + */ + +module m2 { + requires java.compiler; +} diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/Settings.java openjdk-lts-11.0.21+9/test/jdk/tools/launcher/Settings.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/launcher/Settings.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/launcher/Settings.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2017, 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 @@ -25,7 +25,7 @@ /* * @test - * @bug 6994753 7123582 + * @bug 6994753 7123582 8305950 * @summary tests -XshowSettings options * @modules jdk.compiler * jdk.zipfs @@ -69,11 +69,13 @@ private static final String LOCALE_SETTINGS = "Locale settings:"; private static final String SYSTEM_SETTINGS = "Operating System Metrics:"; private static final String STACKSIZE_SETTINGS = "Stack Size:"; + private static final String TZDATA_SETTINGS = "tzdata version"; static void containsAllOptions(TestResult tr) { checkContains(tr, VM_SETTINGS); checkContains(tr, PROP_SETTINGS); checkContains(tr, LOCALE_SETTINGS); + checkContains(tr, TZDATA_SETTINGS); if (System.getProperty("os.name").contains("Linux")) { checkContains(tr, SYSTEM_SETTINGS); } @@ -139,6 +141,7 @@ checkNotContains(tr, VM_SETTINGS); checkNotContains(tr, PROP_SETTINGS); checkContains(tr, LOCALE_SETTINGS); + checkContains(tr, TZDATA_SETTINGS); } static void runTestOptionSystem() throws IOException { diff -Nru openjdk-lts-11.0.20.1+1/test/jdk/tools/pack200/UnpackMalformed.java openjdk-lts-11.0.21+9/test/jdk/tools/pack200/UnpackMalformed.java --- openjdk-lts-11.0.20.1+1/test/jdk/tools/pack200/UnpackMalformed.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jdk/tools/pack200/UnpackMalformed.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * 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 8315135 + * @run main/othervm/timeout=300 -Dcom.sun.java.util.jar.pack.disable.native=false -Xmx8m UnpackMalformed + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.jar.JarOutputStream; +import java.util.jar.Pack200; + +@SuppressWarnings("removal") +public class UnpackMalformed { + public static void main(String[] args) { + try { + ByteArrayInputStream in = new ByteArrayInputStream("foobar".getBytes()); + for (int i=0; i < 1_000; i++) { + try { + JarOutputStream out = new JarOutputStream(new ByteArrayOutputStream()); + Pack200.Unpacker unpacker = Pack200.newUnpacker(); + unpacker.unpack(in, out); + } catch (IOException e) { + } + } + } catch (OutOfMemoryError e) { + System.out.println(e); + throw e; + } + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/jtreg-ext/requires/VMProps.java openjdk-lts-11.0.21+9/test/jtreg-ext/requires/VMProps.java --- openjdk-lts-11.0.20.1+1/test/jtreg-ext/requires/VMProps.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/jtreg-ext/requires/VMProps.java 2023-10-06 05:33:33.000000000 +0000 @@ -324,7 +324,7 @@ * support. */ protected String vmHasJFR() { - return "" + WB.isJFRIncludedInVmBuild(); + return "" + WB.isJFRIncluded(); } /** @@ -398,7 +398,7 @@ * @return true if CDS is supported by the VM to be tested. */ protected String vmCDS() { - return "" + WB.isCDSIncludedInVmBuild(); + return "" + WB.isCDSIncluded(); } /** diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/InheritDocForUserTags/DocTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -49,6 +49,7 @@ void test() { javadoc("-verbose", "-d", "DocTest", + "-sourcepath", System.getProperty("test.src.path"), "-tag", "apiNote:optcm:API Note", "-tag", "implSpec:optcm:Implementation Requirements:", "-tag", "implNote:optcm:Implementation Note:", diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/lib/JavadocTester.java 2023-10-06 05:33:33.000000000 +0000 @@ -112,7 +112,7 @@ * } * * // test methods... - * @Test + * {@literal @}Test * void test() { * javadoc(args); * checkExit(Exit.OK); diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testClassCrossReferences/TestClassCrossReferences.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, 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 @@ -59,7 +59,7 @@ + "title=\"class or interface in javax.swing.text\" class=\"externalLink\">Link to AttributeContext innerclass", "Link to external class BigDecimal", - "Link to external member gcd", "Link to external member URI", @@ -90,7 +90,7 @@ + "title=\"class or interface in javax.swing.text\" class=\"externalLink\">Link to AttributeContext innerclass", "Link to external class BigDecimal", - "Link to external member gcd", "Link to external member URI", diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testExternalOverridenMethod/TestExternalOverridenMethod.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testExternalOverridenMethod/TestExternalOverridenMethod.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testExternalOverridenMethod/TestExternalOverridenMethod.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testExternalOverridenMethod/TestExternalOverridenMethod.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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 @@ -53,12 +53,12 @@ checkOutput("pkg/XReader.html", true, "

          Overrides:
          \n" - + "
          read in class " + "FilterReader
          ", "
          Specified by:
          \n" - + "
          readInt in interface " + "DataInput
          " diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, 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,7 @@ checkOutput("pkg/C1.html", true, //External link. - "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait(long,int)\"", + "href=\"http://java.sun.com/j2se/1.4/docs/api/java/lang/Object.html?is-external=true#wait-long-int-\"", //Member summary table link. "href=\"#method(int,int,java.util.ArrayList)\"", //Anchor test. diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java 1970-01-01 00:00:00.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/pkg/J1.java 2023-10-06 05:33:33.000000000 +0000 @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg; + +/** + *This class has various functions, + * see FTP Site, + * file service for further information + *various functions + *
            + *
          • function1
          • + *
          • function2
          • + *
          • function3
          • + *
          + *special methods + *
            + *
          • method1
          • + *
          • method2
          • + *
          • method3
          • + *
          + */ +public class J1 { + /** + *fields. + */ + protected Object field1; + + /** + *Creates an instance which has various functions. + */ + public J1(){ + } + + /** + *This is aspecial method. + *@param p1 arg1 + */ + public void method1(int p1){ + } + + /** + *See FTP Site for more information. + *@param p1 arg1 + */ + public void method2(int p1){ + } + + /** + *See file service for more information. + *@param p1 arg1 + */ + public void method3(int p1){ + } +} diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testHrefInDocComment/TestHrefInDocComment.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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,7 +23,7 @@ /* * @test - * @bug 4638015 + * @bug 4638015 8248001 * @summary Determine if Hrefs are processed properly when they * appear in doc comments. * @author jamieh diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/javadoc/doclet/testLinkOption/TestLinkOption.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2018, 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 @@ -85,7 +85,7 @@ checkOutput("pkg/B.html", true, "
          A method with html tag the method " - + "getSystemClassLoader()" + " as the parent class loader.
          ", "
          is equivalent to invoking " diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java openjdk-lts-11.0.21+9/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java --- openjdk-lts-11.0.20.1+1/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/jdk/jshell/ExecPtyGetFlagsToSetTest.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,6 +27,7 @@ * @summary Control Char check for pty * @modules jdk.internal.le/jdk.internal.org.jline.terminal * jdk.internal.le/jdk.internal.org.jline.terminal.impl + * jdk.internal.le/jdk.internal.org.jline.terminal.spi * @requires (os.family == "linux") | (os.family == "aix") */ @@ -35,10 +36,11 @@ import jdk.internal.org.jline.terminal.Attributes.ControlChar; import jdk.internal.org.jline.terminal.Attributes.LocalFlag; import jdk.internal.org.jline.terminal.impl.ExecPty; +import jdk.internal.org.jline.terminal.spi.TerminalProvider; public class ExecPtyGetFlagsToSetTest extends ExecPty { - public ExecPtyGetFlagsToSetTest(String name, boolean system) { - super(name, system); + public ExecPtyGetFlagsToSetTest(String name, TerminalProvider.Stream stream) { + super(name, stream); } @Override @@ -48,7 +50,7 @@ public static void main(String[] args) { ExecPtyGetFlagsToSetTest testPty = - new ExecPtyGetFlagsToSetTest("stty", true); + new ExecPtyGetFlagsToSetTest("stty", TerminalProvider.Stream.Output); Attributes attr = new Attributes(); Attributes current = new Attributes(); diff -Nru openjdk-lts-11.0.20.1+1/test/langtools/tools/javac/Paths/Util.sh openjdk-lts-11.0.21+9/test/langtools/tools/javac/Paths/Util.sh --- openjdk-lts-11.0.20.1+1/test/langtools/tools/javac/Paths/Util.sh 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/langtools/tools/javac/Paths/Util.sh 2023-10-06 05:33:33.000000000 +0000 @@ -24,10 +24,10 @@ # Utilities for shell tests : ${TESTSRC=.} ${TESTCLASSES=.} - java="${TESTJAVA+${TESTJAVA}/bin/}java" - javac="${TESTJAVA+${TESTJAVA}/bin/}javac" - jar="${TESTJAVA+${TESTJAVA}/bin/}jar" -jimage="${TESTJAVA+${TESTJAVA}/bin/}jimage" + java="${TESTJAVA+${TESTJAVA}/bin/}java${EXE_SUFFIX}" + javac="${TESTJAVA+${TESTJAVA}/bin/}javac${EXE_SUFFIX}" + jar="${TESTJAVA+${TESTJAVA}/bin/}jar${EXE_SUFFIX}" +jimage="${TESTJAVA+${TESTJAVA}/bin/}jimage${EXE_SUFFIX}" case `uname -s` in Windows*|CYGWIN*|MSYS*|MINGW*) diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/cds/CDSTestUtils.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/cds/CDSTestUtils.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/cds/CDSTestUtils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/cds/CDSTestUtils.java 2023-10-06 05:33:33.000000000 +0000 @@ -261,7 +261,7 @@ for (String s : opts.suffix) cmd.add(s); String[] cmdLine = cmd.toArray(new String[cmd.size()]); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine); + ProcessBuilder pb = ProcessTools.createTestJvm(cmdLine); return executeAndLog(pb, "dump"); } @@ -409,7 +409,7 @@ for (String s : opts.suffix) cmd.add(s); String[] cmdLine = cmd.toArray(new String[cmd.size()]); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, cmdLine); + ProcessBuilder pb = ProcessTools.createTestJvm(cmdLine); return executeAndLog(pb, "exec"); } diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/containers/cgroup/CgroupMetricsTester.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/containers/cgroup/CgroupMetricsTester.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/containers/cgroup/CgroupMetricsTester.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/containers/cgroup/CgroupMetricsTester.java 2023-10-06 05:33:33.000000000 +0000 @@ -31,7 +31,7 @@ interface CgroupMetricsTester { - public static final double ERROR_MARGIN = 0.1; + public static final double ERROR_MARGIN = 0.25; public static final String EMPTY_STR = ""; public void testMemorySubsystem(); diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java 2023-10-06 05:33:33.000000000 +0000 @@ -27,6 +27,7 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; import java.nio.file.Path; import java.nio.file.Paths; @@ -36,6 +37,7 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import jdk.test.lib.Container; import jdk.test.lib.Utils; @@ -164,7 +166,7 @@ Path jdkSrcDir = Paths.get(JDK_UNDER_TEST); Path jdkDstDir = buildDir.resolve("jdk"); Files.createDirectories(jdkDstDir); - Files.walkFileTree(jdkSrcDir, new CopyFileVisitor(jdkSrcDir, jdkDstDir)); + Files.walkFileTree(jdkSrcDir, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new CopyFileVisitor(jdkSrcDir, jdkDstDir)); buildImage(imageName, buildDir); } diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/jfr/AppExecutorHelper.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/jfr/AppExecutorHelper.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/jfr/AppExecutorHelper.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/jfr/AppExecutorHelper.java 2023-10-06 05:33:33.000000000 +0000 @@ -74,7 +74,7 @@ Collections.addAll(arguments, classArguments); } - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, arguments.toArray(new String[0])); + ProcessBuilder pb = ProcessTools.createTestJvm(arguments); return ProcessTools.executeProcess(pb); } } diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/process/ProcessTools.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/process/ProcessTools.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/process/ProcessTools.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/process/ProcessTools.java 2023-10-06 05:33:33.000000000 +0000 @@ -277,19 +277,7 @@ * @return The ProcessBuilder instance representing the java command. */ public static ProcessBuilder createJavaProcessBuilder(List command) { - return createJavaProcessBuilder(false, command); - } - - /** - * Create ProcessBuilder using the java launcher from the jdk to be tested. - *

          - * @param addTestVmAndJavaOptions If true, adds test.vm.opts and test.java.opts - * to the java arguments. - * @param command Arguments to pass to the java command. - * @return The ProcessBuilder instance representing the java command. - */ - public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, List command) { - return createJavaProcessBuilder(addTestVmAndJavaOptions, command.toArray(String[]::new)); + return createJavaProcessBuilder(command.toArray(String[]::new)); } /** @@ -299,18 +287,6 @@ * @return The ProcessBuilder instance representing the java command. */ public static ProcessBuilder createJavaProcessBuilder(String... command) { - return createJavaProcessBuilder(false, command); - } - - /** - * Create ProcessBuilder using the java launcher from the jdk to be tested. - * - * @param addTestVmAndJavaOptions If true, adds test.vm.opts and test.java.opts - * to the java arguments. - * @param command Arguments to pass to the java command. - * @return The ProcessBuilder instance representing the java command. - */ - public static ProcessBuilder createJavaProcessBuilder(boolean addTestVmAndJavaOptions, String... command) { String javapath = JDKToolFinder.getJDKTool("java"); ArrayList args = new ArrayList<>(); @@ -319,10 +295,6 @@ args.add("-cp"); args.add(System.getProperty("java.class.path")); - if (addTestVmAndJavaOptions) { - Collections.addAll(args, Utils.getTestJavaOpts()); - } - Collections.addAll(args, command); // Reporting @@ -345,6 +317,36 @@ } /** + * 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. + * + * @param command Arguments to pass to the java command. + * @return The ProcessBuilder instance representing the java command. + */ + public static ProcessBuilder createTestJvm(List command) { + return createTestJvm(command.toArray(String[]::new)); + } + + /** + * 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. + * + * @param command Arguments to pass to the java command. + * @return The ProcessBuilder instance representing the java command. + */ + public static ProcessBuilder createTestJvm(String... command) { + return createJavaProcessBuilder(Utils.prependTestJavaOpts(command)); + } + + /** * 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. @@ -375,7 +377,7 @@ * @return The output from the process. */ public static OutputAnalyzer executeTestJvm(String... cmds) throws Exception { - ProcessBuilder pb = createJavaProcessBuilder(true, cmds); + ProcessBuilder pb = createTestJvm(cmds); return executeProcess(pb); } diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/security/DerUtils.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/security/DerUtils.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/security/DerUtils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/security/DerUtils.java 2023-10-06 05:33:33.000000000 +0000 @@ -101,9 +101,9 @@ if (expected instanceof ObjectIdentifier) { oid = (ObjectIdentifier)expected; } else if (expected instanceof KnownOIDs) { - oid = new ObjectIdentifier(((KnownOIDs) expected).value()); + oid = ObjectIdentifier.of(((KnownOIDs) expected).value()); } else if (expected instanceof String) { - oid = new ObjectIdentifier(KnownOIDs.findMatch((String)expected).value()); + oid = ObjectIdentifier.of(KnownOIDs.findMatch((String)expected).value()); } else { throw new IllegalArgumentException(expected.toString()); } diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/security/TestCertificate.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/security/TestCertificate.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/security/TestCertificate.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/security/TestCertificate.java 2023-10-06 05:33:33.000000000 +0000 @@ -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 @@ -24,16 +24,21 @@ package jdk.test.lib.security; import java.io.ByteArrayInputStream; -import java.security.cert.CertPath; -import java.security.cert.CertPathValidator; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.PKIXParameters; -import java.security.cert.TrustAnchor; -import java.security.cert.X509Certificate; -import java.util.Collections; -import java.util.Date; -import java.util.List; +import java.io.IOException; +import java.io.SequenceInputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.*; +import java.security.cert.*; +import java.security.cert.Certificate; +import java.util.*; + +import sun.security.tools.keytool.CertAndKeyGen; +import sun.security.x509.X500Name; + +import jdk.test.lib.JDKToolFinder; +import jdk.test.lib.SecurityTools; +import jdk.test.lib.process.OutputAnalyzer; // Certificates taken from old ValWithAnchorByName testcase *** public enum TestCertificate { @@ -122,6 +127,8 @@ "J2GyCaJINsyaI/I2\n" + "-----END CERTIFICATE-----"); + private static final CertificateFactory CERTIFICATE_FACTORY = getCertificateFactory(); + public String serialNumber; public String algorithm; public String subject; @@ -143,22 +150,80 @@ this.keyLength = 2048; } - public X509Certificate generate(CertificateFactory cf) throws CertificateException { + private static CertificateFactory getCertificateFactory() { + try { + return CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + throw new RuntimeException(e); + } + } + + public X509Certificate certificate() throws CertificateException { ByteArrayInputStream is = new ByteArrayInputStream(encoded.getBytes()); - return (X509Certificate) cf.generateCertificate(is); + return (X509Certificate) CERTIFICATE_FACTORY.generateCertificate(is); + } + + public static Collection certificates() throws CertificateException { + ByteArrayInputStream is1 = new ByteArrayInputStream((TestCertificate.ONE.encoded + "\n").getBytes()); + ByteArrayInputStream is2 = new ByteArrayInputStream(TestCertificate.TWO.encoded.getBytes()); + return CERTIFICATE_FACTORY.generateCertificates(new SequenceInputStream(is1, is2)); + } + + public static void certPath() throws CertificateException { + CertPath cp = CERTIFICATE_FACTORY.generateCertPath(List.of(TestCertificate.ONE.certificate(), + TestCertificate.TWO.certificate())); + + // Get the encoded form of the CertPath we made + byte[] encoded = cp.getEncoded("PKCS7"); + CERTIFICATE_FACTORY.generateCertPath(new ByteArrayInputStream(encoded), "PKCS7"); } - public static void generateChain(boolean selfSignedTest) throws Exception { + public static void keyToolTest() throws Exception { + String config = + "\n" + + "\n" + + " \n" + + " true\n" + + " true\n" + + " \n" + + ""; + Files.writeString(Path.of("config.jfc"), config); + + SecurityTools.keytool("-J-XX:StartFlightRecording=filename=keytool.jfr,settings=config.jfc", + "-genkeypair", "-alias", "testkey", "-keyalg", "RSA", "-keysize", "2048", "-dname", + "CN=8292033.oracle.com,OU=JPG,C=US", "-keypass", "changeit", + "-validity", "365", "-keystore", "keystore.pkcs12", "-storepass", "changeit") + .shouldHaveExitValue(0); + // The keytool command will load the keystore and call CertificateFactory.generateCertificate + jfrTool("keytool.jfr") + .shouldContain("8292033.oracle.com") // should record our new cert + .shouldNotContain("algorithm = N/A") // shouldn't record cert under construction + .shouldHaveExitValue(0); + } + + private static OutputAnalyzer jfrTool(String jfrFile) throws Exception { + ProcessBuilder pb = new ProcessBuilder(); + pb.command(new String[] { JDKToolFinder.getJDKTool("jfr"), "print", "--events", + "jdk.X509Certificate", jfrFile}); + return new OutputAnalyzer(pb.start()); + } + + public static void generateChain(boolean selfSignedTest, boolean trustAnchorCert) throws Exception { // Do path validation as if it is always Tue, 06 Sep 2016 22:12:21 GMT // This value is within the lifetimes of all certificates. Date testDate = new Date(1473199941000L); CertificateFactory cf = CertificateFactory.getInstance("X.509"); - X509Certificate c1 = TestCertificate.ONE.generate(cf); - X509Certificate c2 = TestCertificate.TWO.generate(cf); - X509Certificate ca = TestCertificate.ROOT_CA.generate(cf); - - TrustAnchor ta = new TrustAnchor(ca, null); + X509Certificate c1 = TestCertificate.ONE.certificate(); + X509Certificate c2 = TestCertificate.TWO.certificate(); + X509Certificate ca = TestCertificate.ROOT_CA.certificate(); + + TrustAnchor ta; + if (trustAnchorCert) { + ta = new TrustAnchor(ca, null); + } else { + ta = new TrustAnchor(ca.getIssuerX500Principal(), ca.getPublicKey(), null); + } CertPathValidator validator = CertPathValidator.getInstance("PKIX"); PKIXParameters params = new PKIXParameters(Collections.singleton(ta)); @@ -172,4 +237,4 @@ validator.validate(path, params); } } -} \ No newline at end of file +} diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/security/timestamp/TsaSigner.java 2023-10-06 05:33:33.000000000 +0000 @@ -170,7 +170,7 @@ String policyId = respParam.policyId(); print("policyId", policyId); - tstInfoOut.putOID(new ObjectIdentifier(policyId)); + tstInfoOut.putOID(ObjectIdentifier.of(policyId)); String digestAlgo = respParam.digestAlgo(); print("digestAlgo", digestAlgo); @@ -204,7 +204,7 @@ eContentOut.putOctetString(tstInfoSeqData); ContentInfo eContentInfo = new ContentInfo( - new ObjectIdentifier("1.2.840.113549.1.9.16.1.4"), + ObjectIdentifier.of("1.2.840.113549.1.9.16.1.4"), new DerValue(eContentOut.toByteArray())); String defaultSigAlgo = AlgorithmId.getDefaultSigAlgForKey( diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/util/FileUtils.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/util/FileUtils.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/util/FileUtils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/util/FileUtils.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -23,6 +23,8 @@ package jdk.test.lib.util; +import java.io.BufferedReader; +import java.io.InputStreamReader; import java.io.IOException; import java.io.PrintStream; import java.io.UncheckedIOException; @@ -41,6 +43,8 @@ import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.TimeUnit; import jdk.test.lib.Platform; @@ -239,6 +243,93 @@ } /** + * Checks whether all file systems are accessible. This is performed + * by checking free disk space on all mounted file systems via a + * separate, spawned process. File systems are considered to be + * accessible if this process completes successfully before a given + * fixed duration has elapsed. + * + * @implNote On Unix this executes the {@code df} command in a separate + * process and on Windows always returns {@code true}. + * + * @return whether file systems appear to be accessible + * + * @throws RuntimeException if there are duplicate mount points or some + * other execution problem occurs + */ + public static boolean areAllMountPointsAccessible() { + final AtomicBoolean areMountPointsOK = new AtomicBoolean(true); + if (!IS_WINDOWS) { + Thread thr = new Thread(() -> { + try { + Process proc = new ProcessBuilder("df").start(); + BufferedReader reader = new BufferedReader + (new InputStreamReader(proc.getInputStream())); + // Skip the first line as it is the "df" output header. + if (reader.readLine() != null ) { + String prevMountPoint = null, mountPoint = null; + while ((mountPoint = reader.readLine()) != null) { + if (prevMountPoint != null && + mountPoint.equals(prevMountPoint)) { + throw new RuntimeException + ("System configuration error: " + + "duplicate mount point " + mountPoint + + " detected"); + } + prevMountPoint = mountPoint; + } + } + + try { + proc.waitFor(90, TimeUnit.SECONDS); + } catch (InterruptedException ignored) { + } + try { + int exitValue = proc.exitValue(); + if (exitValue != 0) { + System.err.printf("df process exited with %d != 0%n", + exitValue); + areMountPointsOK.set(false); + } + } catch (IllegalThreadStateException ignored) { + System.err.println("df command apparently hung"); + areMountPointsOK.set(false); + } + } catch (IOException ioe) { + throw new RuntimeException(ioe); + }; + }); + + final AtomicReference throwableReference = + new AtomicReference(); + thr.setUncaughtExceptionHandler( + new Thread.UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + throwableReference.set(e); + } + }); + + thr.start(); + try { + thr.join(120*1000L); + } catch (InterruptedException ie) { + throw new RuntimeException(ie); + } + + Throwable uncaughtException = (Throwable)throwableReference.get(); + if (uncaughtException != null) { + throw new RuntimeException(uncaughtException); + } + + if (thr.isAlive()) { + throw new RuntimeException("df thread did not join in time"); + } + } + + return areMountPointsOK.get(); + } + + /** * List the open file descriptors (if supported by the 'lsof' command). * @param ps a printStream to send the output to * @throws UncheckedIOException if an error occurs diff -Nru openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/Utils.java openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/Utils.java --- openjdk-lts-11.0.20.1+1/test/lib/jdk/test/lib/Utils.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/jdk/test/lib/Utils.java 2023-10-06 05:33:33.000000000 +0000 @@ -194,6 +194,18 @@ } /** + * Combines given arguments with default JTReg arguments for a jvm running a test. + * This is the combination of JTReg arguments test.vm.opts and test.java.opts + * @return The combination of JTReg test java options and user args. + */ + public static String[] prependTestJavaOpts(String... userArgs) { + List opts = new ArrayList(); + Collections.addAll(opts, getTestJavaOpts()); + Collections.addAll(opts, userArgs); + return opts.toArray(new String[0]); + } + + /** * Removes any options specifying which GC to use, for example "-XX:+UseG1GC". * Removes any options matching: -XX:(+/-)Use*GC * Used when a test need to set its own GC version. Then any diff -Nru openjdk-lts-11.0.20.1+1/test/lib/sun/hotspot/code/Compiler.java openjdk-lts-11.0.21+9/test/lib/sun/hotspot/code/Compiler.java --- openjdk-lts-11.0.20.1+1/test/lib/sun/hotspot/code/Compiler.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/sun/hotspot/code/Compiler.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * 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 diff -Nru openjdk-lts-11.0.20.1+1/test/lib/sun/hotspot/WhiteBox.java openjdk-lts-11.0.21+9/test/lib/sun/hotspot/WhiteBox.java --- openjdk-lts-11.0.20.1+1/test/lib/sun/hotspot/WhiteBox.java 2023-08-23 05:22:04.000000000 +0000 +++ openjdk-lts-11.0.21+9/test/lib/sun/hotspot/WhiteBox.java 2023-10-06 05:33:33.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -520,8 +520,8 @@ public native boolean isShared(Object o); public native boolean isSharedClass(Class c); public native boolean areSharedStringsIgnored(); - public native boolean isCDSIncludedInVmBuild(); - public native boolean isJFRIncludedInVmBuild(); + public native boolean isCDSIncluded(); + public native boolean isJFRIncluded(); public native boolean isJavaHeapArchiveSupported(); public native Object getResolvedReferences(Class c); public native boolean areOpenArchiveHeapObjectsMapped(); @@ -542,6 +542,8 @@ String procSelfCgroup, String procSelfMountinfo); public native void printOsInfo(); + public native long hostPhysicalMemory(); + public native long hostPhysicalSwap(); // Decoder public native void disableElfSectionCache();