mirror of
https://github.com/openjdk/jdk16u.git
synced 2025-12-10 14:50:36 -06:00
Compare commits
68 Commits
jdk-16.0.2
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dcedb672b | ||
|
|
3b56f0b15c | ||
|
|
6d8f828dd6 | ||
|
|
b3b4dc32a6 | ||
|
|
d2d9533566 | ||
|
|
7616b2c053 | ||
|
|
375be1710a | ||
|
|
6f948a7b02 | ||
|
|
53dd617e59 | ||
|
|
a680794c00 | ||
|
|
3ceb080aae | ||
|
|
b609c519ef | ||
|
|
5fcdc03000 | ||
|
|
410f742b98 | ||
|
|
e0060a32ba | ||
|
|
5311c4d454 | ||
|
|
6fc68c2fbb | ||
|
|
8491a2ef06 | ||
|
|
e84e18580d | ||
|
|
860ca3fd75 | ||
|
|
d917b81bc9 | ||
|
|
319621c31c | ||
|
|
dbb6f4c1ee | ||
|
|
9a4b6db45f | ||
|
|
1116b75741 | ||
|
|
cb295fb931 | ||
|
|
8714642b13 | ||
|
|
c44d517326 | ||
|
|
0a52d016b8 | ||
|
|
ce14719df1 | ||
|
|
ee4633de70 | ||
|
|
f43fbb7993 | ||
|
|
e4651f3adc | ||
|
|
4ea26b8918 | ||
|
|
019c81db21 | ||
|
|
4c20935d66 | ||
|
|
cce99e57e1 | ||
|
|
32eb4f865a | ||
|
|
5d5b122e4f | ||
|
|
fcb4688e46 | ||
|
|
71e6dab1ae | ||
|
|
b055d95c5f | ||
|
|
19faaa007c | ||
|
|
49dda6f5f6 | ||
|
|
2dbfed67cb | ||
|
|
8ddb1d8453 | ||
|
|
2826d30494 | ||
|
|
4f5421ef77 | ||
|
|
048040fe2b | ||
|
|
426cb6ad2a | ||
|
|
27c84494a5 | ||
|
|
31940f15cf | ||
|
|
3464a0f12c | ||
|
|
72be1e24be | ||
|
|
e99595bbe4 | ||
|
|
566703ac42 | ||
|
|
484087bdc7 | ||
|
|
ba7c640201 | ||
|
|
beaf240ee5 | ||
|
|
467739ec9e | ||
|
|
ad5d0ee74a | ||
|
|
6ca2b075b9 | ||
|
|
b1169c05fc | ||
|
|
ec89262d37 | ||
|
|
99d0793ecd | ||
|
|
74bc4541fa | ||
|
|
0481fd43a3 | ||
|
|
83b27fbb73 |
@ -319,6 +319,7 @@
|
||||
<li>To install on an apt-based Linux, try running <code>sudo apt-get install libfreetype6-dev</code>.</li>
|
||||
<li>To install on an rpm-based Linux, try running <code>sudo yum install freetype-devel</code>.</li>
|
||||
<li>To install on Alpine Linux, try running <code>sudo apk add freetype-dev</code>.</li>
|
||||
<li>To install on macOS, try running <code>brew install freetype</code>.</li>
|
||||
</ul>
|
||||
<p>Use <code>--with-freetype-include=<path></code> and <code>--with-freetype-lib=<path></code> if <code>configure</code> does not automatically locate the platform FreeType files.</p>
|
||||
<h3 id="cups">CUPS</h3>
|
||||
|
||||
@ -451,6 +451,7 @@ rather than bundling the JDK's own copy.
|
||||
* To install on an rpm-based Linux, try running `sudo yum install
|
||||
freetype-devel`.
|
||||
* To install on Alpine Linux, try running `sudo apk add freetype-dev`.
|
||||
* To install on macOS, try running `brew install freetype`.
|
||||
|
||||
Use `--with-freetype-include=<path>` and `--with-freetype-lib=<path>`
|
||||
if `configure` does not automatically locate the platform FreeType files.
|
||||
|
||||
@ -240,11 +240,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_SYMBOLS],
|
||||
[AS_HELP_STRING([--with-native-debug-symbols],
|
||||
[set the native debug symbol configuration (none, internal, external, zipped) @<:@varying@:>@])],
|
||||
[
|
||||
if test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
if test "x$withval" = xexternal || test "x$withval" = xzipped; then
|
||||
AC_MSG_ERROR([AIX only supports the parameters 'none' and 'internal' for --with-native-debug-symbols])
|
||||
fi
|
||||
elif test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
if test "x$OPENJDK_TARGET_OS" = xwindows; then
|
||||
if test "x$withval" = xinternal; then
|
||||
AC_MSG_ERROR([Windows does not support the parameter 'internal' for --with-native-debug-symbols])
|
||||
fi
|
||||
@ -254,12 +250,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_DEBUG_SYMBOLS],
|
||||
if test "x$STATIC_BUILD" = xtrue; then
|
||||
with_native_debug_symbols="none"
|
||||
else
|
||||
if test "x$OPENJDK_TARGET_OS" = xaix; then
|
||||
# AIX doesn't support 'external' so use 'internal' as default
|
||||
with_native_debug_symbols="internal"
|
||||
else
|
||||
with_native_debug_symbols="external"
|
||||
fi
|
||||
with_native_debug_symbols="external"
|
||||
fi
|
||||
])
|
||||
AC_MSG_RESULT([$with_native_debug_symbols])
|
||||
|
||||
@ -33,7 +33,7 @@ DEFAULT_VERSION_PATCH=0
|
||||
DEFAULT_VERSION_EXTRA1=0
|
||||
DEFAULT_VERSION_EXTRA2=0
|
||||
DEFAULT_VERSION_EXTRA3=0
|
||||
DEFAULT_VERSION_DATE=2021-07-21
|
||||
DEFAULT_VERSION_DATE=2021-07-20
|
||||
DEFAULT_VERSION_CLASSFILE_MAJOR=60 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
|
||||
DEFAULT_VERSION_CLASSFILE_MINOR=0
|
||||
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="15 16"
|
||||
|
||||
@ -974,6 +974,13 @@ define SetupNativeCompilationBody
|
||||
$(CD) $$($1_SYMBOLS_DIR) && \
|
||||
$$($1_OBJCOPY) --add-gnu-debuglink=$$($1_DEBUGINFO_FILES) $$($1_TARGET)
|
||||
|
||||
else ifeq ($(call isTargetOs, aix), true)
|
||||
# AIX does not provide the equivalent of OBJCOPY to extract debug symbols,
|
||||
# so we copy the compiled object with symbols to the .debuginfo file, which
|
||||
# happens prior to the STRIP_CMD on the original target object file.
|
||||
$1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo
|
||||
$1_CREATE_DEBUGINFO_CMDS := $(CP) $$($1_TARGET) $$($1_DEBUGINFO_FILES)
|
||||
|
||||
else ifeq ($(call isTargetOs, macosx), true)
|
||||
$1_DEBUGINFO_FILES := \
|
||||
$$($1_SYMBOLS_DIR)/$$($1_BASENAME).dSYM/Contents/Info.plist \
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
Owner: CN=Sonera Class2 CA, O=Sonera, C=FI
|
||||
Issuer: CN=Sonera Class2 CA, O=Sonera, C=FI
|
||||
Serial number: 1d
|
||||
Valid from: Fri Apr 06 07:29:40 GMT 2001 until: Tue Apr 06 07:29:40 GMT 2021
|
||||
Signature algorithm name: SHA1withRSA
|
||||
Subject Public Key Algorithm: 2048-bit RSA key
|
||||
Version: 3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
|
||||
MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
|
||||
MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
|
||||
BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
|
||||
hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
|
||||
Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
|
||||
5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
|
||||
3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
|
||||
vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
|
||||
8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
|
||||
DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
|
||||
MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
|
||||
zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
|
||||
3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
|
||||
FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
|
||||
Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
|
||||
ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
|
||||
-----END CERTIFICATE-----
|
||||
@ -674,6 +674,11 @@ void MacroAssembler::call_VM_base(Register oop_result,
|
||||
// do the call, remove parameters
|
||||
MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments, &l);
|
||||
|
||||
// lr could be poisoned with PAC signature during throw_pending_exception
|
||||
// if it was tail-call optimized by compiler, since lr is not callee-saved
|
||||
// reload it with proper value
|
||||
adr(lr, l);
|
||||
|
||||
// reset last Java frame
|
||||
// Only interpreter should have to clear fp
|
||||
reset_last_Java_frame(true);
|
||||
|
||||
@ -1064,54 +1064,6 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
|
||||
return localtime_r(clock, res);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// runtime exit support
|
||||
|
||||
// Note: os::shutdown() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::shutdown(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::shutdown() {
|
||||
|
||||
// allow PerfMemory to attempt cleanup of any persistent resources
|
||||
perfMemory_exit();
|
||||
|
||||
// needs to remove object in file system
|
||||
AttachListener::abort();
|
||||
|
||||
// flush buffered output, finish log files
|
||||
ostream_abort();
|
||||
|
||||
// Check for abort hook
|
||||
abort_hook_t abort_hook = Arguments::abort_hook();
|
||||
if (abort_hook != NULL) {
|
||||
abort_hook();
|
||||
}
|
||||
}
|
||||
|
||||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core, void* siginfo, const void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
::abort(); // dump core
|
||||
}
|
||||
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
// Die immediately, no exit hook, no abort hook, no cleanup.
|
||||
// Dump a core file, if possible, for debugging.
|
||||
void os::die() {
|
||||
if (TestUnresponsiveErrorHandler && !CreateCoredumpOnCrash) {
|
||||
// For TimeoutInErrorHandlingTest.java, we just kill the VM
|
||||
// and don't take the time to generate a core file.
|
||||
os::signal_raise(SIGKILL);
|
||||
} else {
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
|
||||
intx os::current_thread_id() {
|
||||
return (intx)pthread_self();
|
||||
}
|
||||
|
||||
@ -929,56 +929,6 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
|
||||
return localtime_r(clock, res);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// runtime exit support
|
||||
|
||||
// Note: os::shutdown() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::shutdown(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::shutdown() {
|
||||
|
||||
// allow PerfMemory to attempt cleanup of any persistent resources
|
||||
perfMemory_exit();
|
||||
|
||||
// needs to remove object in file system
|
||||
AttachListener::abort();
|
||||
|
||||
// flush buffered output, finish log files
|
||||
ostream_abort();
|
||||
|
||||
// Check for abort hook
|
||||
abort_hook_t abort_hook = Arguments::abort_hook();
|
||||
if (abort_hook != NULL) {
|
||||
abort_hook();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core, void* siginfo, const void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
::abort(); // dump core
|
||||
}
|
||||
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
// Die immediately, no exit hook, no abort hook, no cleanup.
|
||||
// Dump a core file, if possible, for debugging.
|
||||
void os::die() {
|
||||
if (TestUnresponsiveErrorHandler && !CreateCoredumpOnCrash) {
|
||||
// For TimeoutInErrorHandlingTest.java, we just kill the VM
|
||||
// and don't take the time to generate a core file.
|
||||
os::signal_raise(SIGKILL);
|
||||
} else {
|
||||
// _exit() on BsdThreads only kills current thread
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Information of current thread in variety of formats
|
||||
pid_t os::Bsd::gettid() {
|
||||
int retval = -1;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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,7 +24,6 @@
|
||||
|
||||
// no precompiled headers
|
||||
#include "jvm.h"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
@ -66,7 +65,6 @@
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "signals_posix.hpp"
|
||||
#include "semaphore_posix.hpp"
|
||||
#include "services/attachListener.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "services/runtimeService.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
@ -1429,58 +1427,6 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
|
||||
return localtime_r(clock, res);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// runtime exit support
|
||||
|
||||
// Note: os::shutdown() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::shutdown(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::shutdown() {
|
||||
|
||||
// allow PerfMemory to attempt cleanup of any persistent resources
|
||||
perfMemory_exit();
|
||||
|
||||
// needs to remove object in file system
|
||||
AttachListener::abort();
|
||||
|
||||
// flush buffered output, finish log files
|
||||
ostream_abort();
|
||||
|
||||
// Check for abort hook
|
||||
abort_hook_t abort_hook = Arguments::abort_hook();
|
||||
if (abort_hook != NULL) {
|
||||
abort_hook();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::abort(bool dump_core, void* siginfo, const void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
if (DumpPrivateMappingsInCore) {
|
||||
ClassLoader::close_jrt_image();
|
||||
}
|
||||
::abort(); // dump core
|
||||
}
|
||||
|
||||
::exit(1);
|
||||
}
|
||||
|
||||
// Die immediately, no exit hook, no abort hook, no cleanup.
|
||||
// Dump a core file, if possible, for debugging.
|
||||
void os::die() {
|
||||
if (TestUnresponsiveErrorHandler && !CreateCoredumpOnCrash) {
|
||||
// For TimeoutInErrorHandlingTest.java, we just kill the VM
|
||||
// and don't take the time to generate a core file.
|
||||
os::signal_raise(SIGKILL);
|
||||
} else {
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
|
||||
// thread_id is kernel thread id (similar to Solaris LWP id)
|
||||
intx os::current_thread_id() { return os::Linux::gettid(); }
|
||||
int os::current_process_id() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 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
|
||||
@ -22,19 +22,26 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "jvm.h"
|
||||
#ifdef LINUX
|
||||
#include "classfile/classLoader.hpp"
|
||||
#endif
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "os_posix.inline.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/globals_extension.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "services/attachListener.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "runtime/perfMemory.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/events.hpp"
|
||||
#include "utilities/formatBuffer.hpp"
|
||||
@ -1812,3 +1819,56 @@ int os::PlatformMonitor::wait(jlong millis) {
|
||||
return OS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// runtime exit support
|
||||
|
||||
// Note: os::shutdown() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::shutdown(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
void os::shutdown() {
|
||||
|
||||
// allow PerfMemory to attempt cleanup of any persistent resources
|
||||
perfMemory_exit();
|
||||
|
||||
// needs to remove object in file system
|
||||
AttachListener::abort();
|
||||
|
||||
// flush buffered output, finish log files
|
||||
ostream_abort();
|
||||
|
||||
// Check for abort hook
|
||||
abort_hook_t abort_hook = Arguments::abort_hook();
|
||||
if (abort_hook != NULL) {
|
||||
abort_hook();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Note: os::abort() might be called very early during initialization, or
|
||||
// called from signal handler. Before adding something to os::abort(), make
|
||||
// sure it is async-safe and can handle partially initialized VM.
|
||||
// Also note we can abort while other threads continue to run, so we can
|
||||
// easily trigger secondary faults in those threads. To reduce the likelihood
|
||||
// of that we use _exit rather than exit, so that no atexit hooks get run.
|
||||
// But note that os::shutdown() could also trigger secondary faults.
|
||||
void os::abort(bool dump_core, void* siginfo, const void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
LINUX_ONLY(if (DumpPrivateMappingsInCore) ClassLoader::close_jrt_image();)
|
||||
::abort(); // dump core
|
||||
}
|
||||
::_exit(1);
|
||||
}
|
||||
|
||||
// Die immediately, no exit hook, no abort hook, no cleanup.
|
||||
// Dump a core file, if possible, for debugging.
|
||||
void os::die() {
|
||||
if (TestUnresponsiveErrorHandler && !CreateCoredumpOnCrash) {
|
||||
// For TimeoutInErrorHandlingTest.java, we just kill the VM
|
||||
// and don't take the time to generate a core file.
|
||||
os::signal_raise(SIGKILL);
|
||||
} else {
|
||||
::abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -974,7 +974,7 @@ void RangeCheckEliminator::calc_bounds(BlockBegin *block, BlockBegin *loop_heade
|
||||
} else {
|
||||
// Has no upper bound
|
||||
Instruction *instr = ai->length();
|
||||
if (instr != NULL) instr = ai->array();
|
||||
if (instr == NULL) instr = ai->array();
|
||||
update_bound(pushed, ai->index(), Instruction::lss, instr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1527,7 +1527,7 @@ bool ClassHierarchyWalker::witnessed_reabstraction_in_supers(Klass* k) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
assert(false, "root method not found");
|
||||
// Miranda.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -110,10 +110,6 @@ void ShenandoahArguments::initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(ParallelRefProcEnabled)) {
|
||||
FLAG_SET_DEFAULT(ParallelRefProcEnabled, true);
|
||||
}
|
||||
|
||||
if (ShenandoahRegionSampling && FLAG_IS_DEFAULT(PerfDataMemorySize)) {
|
||||
// When sampling is enabled, max out the PerfData memory to get more
|
||||
// Shenandoah data in, including Matrix.
|
||||
|
||||
@ -151,6 +151,9 @@ jint ShenandoahHeap::initialize() {
|
||||
Universe::check_alignment(init_byte_size, reg_size_bytes, "Shenandoah heap");
|
||||
|
||||
_num_regions = ShenandoahHeapRegion::region_count();
|
||||
assert(_num_regions == (max_byte_size / reg_size_bytes),
|
||||
"Regions should cover entire heap exactly: " SIZE_FORMAT " != " SIZE_FORMAT "/" SIZE_FORMAT,
|
||||
_num_regions, max_byte_size, reg_size_bytes);
|
||||
|
||||
// Now we know the number of regions, initialize the heuristics.
|
||||
initialize_heuristics();
|
||||
|
||||
@ -541,10 +541,10 @@ void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
|
||||
}
|
||||
|
||||
// Make sure region size is at least one large page, if enabled.
|
||||
// Otherwise, uncommitting one region may falsely uncommit the adjacent
|
||||
// regions too.
|
||||
// Also see shenandoahArguments.cpp, where it handles UseLargePages.
|
||||
if (UseLargePages && ShenandoahUncommit) {
|
||||
// The heap sizes would be rounded by heap initialization code by
|
||||
// page size, so we need to round up the region size too, to cover
|
||||
// the heap exactly.
|
||||
if (UseLargePages) {
|
||||
region_size = MAX2(region_size, os::large_page_size());
|
||||
}
|
||||
|
||||
@ -573,7 +573,7 @@ void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
|
||||
RegionSizeBytesMask = RegionSizeBytes - 1;
|
||||
|
||||
guarantee(RegionCount == 0, "we should only set it once");
|
||||
RegionCount = max_heap_size / RegionSizeBytes;
|
||||
RegionCount = align_up(max_heap_size, RegionSizeBytes) / RegionSizeBytes;
|
||||
guarantee(RegionCount >= MIN_NUM_REGIONS, "Should have at least minimum regions");
|
||||
|
||||
guarantee(HumongousThresholdWords == 0, "we should only set it once");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 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
|
||||
@ -199,12 +199,16 @@ static bool stack_trace_precondition(const ObjectSample* sample) {
|
||||
|
||||
class StackTraceBlobInstaller {
|
||||
private:
|
||||
const JfrStackTraceRepository& _stack_trace_repo;
|
||||
BlobCache _cache;
|
||||
const JfrStackTrace* resolve(const ObjectSample* sample);
|
||||
void install(ObjectSample* sample);
|
||||
const JfrStackTrace* resolve(const ObjectSample* sample) const;
|
||||
public:
|
||||
StackTraceBlobInstaller(const JfrStackTraceRepository& stack_trace_repo);
|
||||
StackTraceBlobInstaller() : _cache(JfrOptionSet::old_object_queue_size()) {
|
||||
prepare_for_resolution();
|
||||
}
|
||||
~StackTraceBlobInstaller() {
|
||||
JfrStackTraceRepository::clear_leak_profiler();
|
||||
}
|
||||
void sample_do(ObjectSample* sample) {
|
||||
if (stack_trace_precondition(sample)) {
|
||||
install(sample);
|
||||
@ -212,15 +216,6 @@ class StackTraceBlobInstaller {
|
||||
}
|
||||
};
|
||||
|
||||
StackTraceBlobInstaller::StackTraceBlobInstaller(const JfrStackTraceRepository& stack_trace_repo) :
|
||||
_stack_trace_repo(stack_trace_repo), _cache(JfrOptionSet::old_object_queue_size()) {
|
||||
prepare_for_resolution();
|
||||
}
|
||||
|
||||
const JfrStackTrace* StackTraceBlobInstaller::resolve(const ObjectSample* sample) {
|
||||
return _stack_trace_repo.lookup(sample->stack_trace_hash(), sample->stack_trace_id());
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
static void validate_stack_trace(const ObjectSample* sample, const JfrStackTrace* stack_trace) {
|
||||
assert(!sample->has_stacktrace(), "invariant");
|
||||
@ -230,6 +225,10 @@ static void validate_stack_trace(const ObjectSample* sample, const JfrStackTrace
|
||||
}
|
||||
#endif
|
||||
|
||||
inline const JfrStackTrace* StackTraceBlobInstaller::resolve(const ObjectSample* sample) const {
|
||||
return JfrStackTraceRepository::lookup_for_leak_profiler(sample->stack_trace_hash(), sample->stack_trace_id());
|
||||
}
|
||||
|
||||
void StackTraceBlobInstaller::install(ObjectSample* sample) {
|
||||
JfrBlobHandle blob = _cache.get(sample);
|
||||
if (blob.valid()) {
|
||||
@ -242,23 +241,23 @@ void StackTraceBlobInstaller::install(ObjectSample* sample) {
|
||||
writer.write_type(TYPE_STACKTRACE);
|
||||
writer.write_count(1);
|
||||
ObjectSampleCheckpoint::write_stacktrace(stack_trace, writer);
|
||||
blob = writer.move();
|
||||
blob = writer.copy();
|
||||
_cache.put(sample, blob);
|
||||
sample->set_stacktrace(blob);
|
||||
}
|
||||
|
||||
static void install_stack_traces(const ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) {
|
||||
static void install_stack_traces(const ObjectSampler* sampler) {
|
||||
assert(sampler != NULL, "invariant");
|
||||
const ObjectSample* const last = sampler->last();
|
||||
if (last != sampler->last_resolved()) {
|
||||
ResourceMark rm;
|
||||
JfrKlassUnloading::sort();
|
||||
StackTraceBlobInstaller installer(stack_trace_repo);
|
||||
StackTraceBlobInstaller installer;
|
||||
iterate_samples(installer);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) {
|
||||
void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler) {
|
||||
assert(sampler != NULL, "invariant");
|
||||
assert(LeakProfiler::is_running(), "invariant");
|
||||
JavaThread* const thread = JavaThread::current();
|
||||
@ -267,7 +266,7 @@ void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler, JfrStackT
|
||||
ThreadInVMfromNative transition(thread);
|
||||
MutexLocker lock(ClassLoaderDataGraph_lock);
|
||||
// the lock is needed to ensure the unload lists do not grow in the middle of inspection.
|
||||
install_stack_traces(sampler, stack_trace_repo);
|
||||
install_stack_traces(sampler);
|
||||
}
|
||||
|
||||
static bool is_klass_unloaded(traceid klass_id) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 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
|
||||
@ -33,7 +33,6 @@ class InstanceKlass;
|
||||
class JavaThread;
|
||||
class JfrCheckpointWriter;
|
||||
class JfrStackTrace;
|
||||
class JfrStackTraceRepository;
|
||||
class Klass;
|
||||
class ObjectSample;
|
||||
class ObjectSampleMarker;
|
||||
@ -53,7 +52,7 @@ class ObjectSampleCheckpoint : AllStatic {
|
||||
static void on_type_set(JfrCheckpointWriter& writer);
|
||||
static void on_type_set_unload(JfrCheckpointWriter& writer);
|
||||
static void on_thread_exit(JavaThread* jt);
|
||||
static void on_rotation(const ObjectSampler* sampler, JfrStackTraceRepository& repo);
|
||||
static void on_rotation(const ObjectSampler* sampler);
|
||||
};
|
||||
|
||||
#endif // SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLECHECKPOINT_HPP
|
||||
|
||||
@ -158,12 +158,23 @@ static traceid get_thread_id(JavaThread* thread) {
|
||||
return tl->thread_id();
|
||||
}
|
||||
|
||||
static void record_stacktrace(JavaThread* thread) {
|
||||
assert(thread != NULL, "invariant");
|
||||
if (JfrEventSetting::has_stacktrace(EventOldObjectSample::eventId)) {
|
||||
JfrStackTraceRepository::record_and_cache(thread);
|
||||
class RecordStackTrace {
|
||||
private:
|
||||
JavaThread* _jt;
|
||||
bool _enabled;
|
||||
public:
|
||||
RecordStackTrace(JavaThread* jt) : _jt(jt),
|
||||
_enabled(JfrEventSetting::has_stacktrace(EventOldObjectSample::eventId)) {
|
||||
if (_enabled) {
|
||||
JfrStackTraceRepository::record_for_leak_profiler(jt);
|
||||
}
|
||||
}
|
||||
}
|
||||
~RecordStackTrace() {
|
||||
if (_enabled) {
|
||||
_jt->jfr_thread_local()->clear_cached_stack_trace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void ObjectSampler::sample(HeapWord* obj, size_t allocated, JavaThread* thread) {
|
||||
assert(thread != NULL, "invariant");
|
||||
@ -172,7 +183,7 @@ void ObjectSampler::sample(HeapWord* obj, size_t allocated, JavaThread* thread)
|
||||
if (thread_id == 0) {
|
||||
return;
|
||||
}
|
||||
record_stacktrace(thread);
|
||||
RecordStackTrace rst(thread);
|
||||
// try enter critical section
|
||||
JfrTryLock tryLock(&_lock);
|
||||
if (!tryLock.acquired()) {
|
||||
|
||||
@ -809,12 +809,11 @@ class MethodIteratorHost {
|
||||
bool operator()(KlassPtr klass) {
|
||||
if (_method_used_predicate(klass)) {
|
||||
const InstanceKlass* ik = InstanceKlass::cast(klass);
|
||||
const int len = ik->methods()->length();
|
||||
Filter filter(ik->previous_versions() != NULL ? len : 0);
|
||||
while (ik != NULL) {
|
||||
const int len = ik->methods()->length();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
MethodPtr method = ik->methods()->at(i);
|
||||
if (_method_flag_predicate(method) && filter(i)) {
|
||||
if (_method_flag_predicate(method)) {
|
||||
_method_cb(method);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -100,7 +100,6 @@ class JfrTraceId : public AllStatic {
|
||||
static traceid load_raw(jclass jc);
|
||||
static traceid load_raw(const Thread* thread);
|
||||
static traceid load_raw(const Method* method);
|
||||
static traceid load_raw(const Klass* klass, const Method* method);
|
||||
static traceid load_raw(const ModuleEntry* module);
|
||||
static traceid load_raw(const PackageEntry* package);
|
||||
static traceid load_raw(const ClassLoaderData* cld);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2020, 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
|
||||
@ -437,7 +437,7 @@ void JfrRecorderService::clear() {
|
||||
void JfrRecorderService::pre_safepoint_clear() {
|
||||
_string_pool.clear();
|
||||
_storage.clear();
|
||||
_stack_trace_repository.clear();
|
||||
JfrStackTraceRepository::clear();
|
||||
}
|
||||
|
||||
void JfrRecorderService::invoke_safepoint_clear() {
|
||||
@ -452,7 +452,7 @@ void JfrRecorderService::safepoint_clear() {
|
||||
_string_pool.clear();
|
||||
_storage.clear();
|
||||
_chunkwriter.set_time_stamp();
|
||||
_stack_trace_repository.clear();
|
||||
JfrStackTraceRepository::clear();
|
||||
_checkpoint_manager.end_epoch_shift();
|
||||
}
|
||||
|
||||
@ -539,7 +539,7 @@ void JfrRecorderService::pre_safepoint_write() {
|
||||
if (LeakProfiler::is_running()) {
|
||||
// Exclusive access to the object sampler instance.
|
||||
// The sampler is released (unlocked) later in post_safepoint_write.
|
||||
ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository);
|
||||
ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire());
|
||||
}
|
||||
if (_string_pool.is_modified()) {
|
||||
write_stringpool(_string_pool, _chunkwriter);
|
||||
@ -560,6 +560,7 @@ void JfrRecorderService::invoke_safepoint_write() {
|
||||
void JfrRecorderService::safepoint_write() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
|
||||
_checkpoint_manager.begin_epoch_shift();
|
||||
JfrStackTraceRepository::clear_leak_profiler();
|
||||
if (_string_pool.is_modified()) {
|
||||
write_stringpool(_string_pool, _chunkwriter);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -30,18 +30,38 @@
|
||||
#include "jfr/support/jfrThreadLocal.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
|
||||
static JfrStackTraceRepository* _instance = NULL;
|
||||
/*
|
||||
* There are two separate repository instances.
|
||||
* One instance is dedicated to stacktraces taken as part of the leak profiler subsystem.
|
||||
* It is kept separate because at the point of insertion, it is unclear if a trace will be serialized,
|
||||
* which is a decision postponed and taken during rotation.
|
||||
*/
|
||||
|
||||
JfrStackTraceRepository::JfrStackTraceRepository() : _next_id(0), _entries(0) {
|
||||
memset(_table, 0, sizeof(_table));
|
||||
}
|
||||
static JfrStackTraceRepository* _instance = NULL;
|
||||
static JfrStackTraceRepository* _leak_profiler_instance = NULL;
|
||||
static traceid _next_id = 0;
|
||||
|
||||
JfrStackTraceRepository& JfrStackTraceRepository::instance() {
|
||||
assert(_instance != NULL, "invariant");
|
||||
return *_instance;
|
||||
}
|
||||
|
||||
static JfrStackTraceRepository& leak_profiler_instance() {
|
||||
assert(_leak_profiler_instance != NULL, "invariant");
|
||||
return *_leak_profiler_instance;
|
||||
}
|
||||
|
||||
JfrStackTraceRepository::JfrStackTraceRepository() : _last_entries(0), _entries(0) {
|
||||
memset(_table, 0, sizeof(_table));
|
||||
}
|
||||
|
||||
JfrStackTraceRepository* JfrStackTraceRepository::create() {
|
||||
assert(_instance == NULL, "invariant");
|
||||
assert(_leak_profiler_instance == NULL, "invariant");
|
||||
_leak_profiler_instance = new JfrStackTraceRepository();
|
||||
if (_leak_profiler_instance == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
_instance = new JfrStackTraceRepository();
|
||||
return _instance;
|
||||
}
|
||||
@ -69,12 +89,12 @@ void JfrStackTraceRepository::destroy() {
|
||||
assert(_instance != NULL, "invarinat");
|
||||
delete _instance;
|
||||
_instance = NULL;
|
||||
delete _leak_profiler_instance;
|
||||
_leak_profiler_instance = NULL;
|
||||
}
|
||||
|
||||
static traceid last_id = 0;
|
||||
|
||||
bool JfrStackTraceRepository::is_modified() const {
|
||||
return last_id != _next_id;
|
||||
return _last_entries != _entries;
|
||||
}
|
||||
|
||||
size_t JfrStackTraceRepository::write(JfrChunkWriter& sw, bool clear) {
|
||||
@ -102,26 +122,27 @@ size_t JfrStackTraceRepository::write(JfrChunkWriter& sw, bool clear) {
|
||||
memset(_table, 0, sizeof(_table));
|
||||
_entries = 0;
|
||||
}
|
||||
last_id = _next_id;
|
||||
_last_entries = _entries;
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t JfrStackTraceRepository::clear() {
|
||||
size_t JfrStackTraceRepository::clear(JfrStackTraceRepository& repo) {
|
||||
MutexLocker lock(JfrStacktrace_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (_entries == 0) {
|
||||
if (repo._entries == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (u4 i = 0; i < TABLE_SIZE; ++i) {
|
||||
JfrStackTrace* stacktrace = _table[i];
|
||||
JfrStackTrace* stacktrace = repo._table[i];
|
||||
while (stacktrace != NULL) {
|
||||
JfrStackTrace* next = const_cast<JfrStackTrace*>(stacktrace->next());
|
||||
delete stacktrace;
|
||||
stacktrace = next;
|
||||
}
|
||||
}
|
||||
memset(_table, 0, sizeof(_table));
|
||||
const size_t processed = _entries;
|
||||
_entries = 0;
|
||||
memset(repo._table, 0, sizeof(repo._table));
|
||||
const size_t processed = repo._entries;
|
||||
repo._entries = 0;
|
||||
repo._last_entries = 0;
|
||||
return processed;
|
||||
}
|
||||
|
||||
@ -147,20 +168,23 @@ traceid JfrStackTraceRepository::record(Thread* thread, int skip /* 0 */) {
|
||||
|
||||
traceid JfrStackTraceRepository::record_for(JavaThread* thread, int skip, JfrStackFrame *frames, u4 max_frames) {
|
||||
JfrStackTrace stacktrace(frames, max_frames);
|
||||
return stacktrace.record_safe(thread, skip) ? add(stacktrace) : 0;
|
||||
return stacktrace.record_safe(thread, skip) ? add(instance(), stacktrace) : 0;
|
||||
}
|
||||
|
||||
traceid JfrStackTraceRepository::add(const JfrStackTrace& stacktrace) {
|
||||
traceid tid = instance().add_trace(stacktrace);
|
||||
traceid JfrStackTraceRepository::add(JfrStackTraceRepository& repo, const JfrStackTrace& stacktrace) {
|
||||
traceid tid = repo.add_trace(stacktrace);
|
||||
if (tid == 0) {
|
||||
stacktrace.resolve_linenos();
|
||||
tid = instance().add_trace(stacktrace);
|
||||
tid = repo.add_trace(stacktrace);
|
||||
}
|
||||
assert(tid != 0, "invariant");
|
||||
return tid;
|
||||
}
|
||||
|
||||
void JfrStackTraceRepository::record_and_cache(JavaThread* thread, int skip /* 0 */) {
|
||||
traceid JfrStackTraceRepository::add(const JfrStackTrace& stacktrace) {
|
||||
return add(instance(), stacktrace);
|
||||
}
|
||||
|
||||
void JfrStackTraceRepository::record_for_leak_profiler(JavaThread* thread, int skip /* 0 */) {
|
||||
assert(thread != NULL, "invariant");
|
||||
JfrThreadLocal* const tl = thread->jfr_thread_local();
|
||||
assert(tl != NULL, "invariant");
|
||||
@ -169,7 +193,7 @@ void JfrStackTraceRepository::record_and_cache(JavaThread* thread, int skip /* 0
|
||||
stacktrace.record_safe(thread, skip);
|
||||
const unsigned int hash = stacktrace.hash();
|
||||
if (hash != 0) {
|
||||
tl->set_cached_stack_trace_id(instance().add(stacktrace), hash);
|
||||
tl->set_cached_stack_trace_id(add(leak_profiler_instance(), stacktrace), hash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,9 +220,9 @@ traceid JfrStackTraceRepository::add_trace(const JfrStackTrace& stacktrace) {
|
||||
}
|
||||
|
||||
// invariant is that the entry to be resolved actually exists in the table
|
||||
const JfrStackTrace* JfrStackTraceRepository::lookup(unsigned int hash, traceid id) const {
|
||||
const JfrStackTrace* JfrStackTraceRepository::lookup_for_leak_profiler(unsigned int hash, traceid id) {
|
||||
const size_t index = (hash % TABLE_SIZE);
|
||||
const JfrStackTrace* trace = _table[index];
|
||||
const JfrStackTrace* trace = leak_profiler_instance()._table[index];
|
||||
while (trace != NULL && trace->id() != id) {
|
||||
trace = trace->next();
|
||||
}
|
||||
@ -207,3 +231,12 @@ const JfrStackTrace* JfrStackTraceRepository::lookup(unsigned int hash, traceid
|
||||
assert(trace->id() == id, "invariant");
|
||||
return trace;
|
||||
}
|
||||
|
||||
void JfrStackTraceRepository::clear_leak_profiler() {
|
||||
clear(leak_profiler_instance());
|
||||
}
|
||||
|
||||
size_t JfrStackTraceRepository::clear() {
|
||||
clear_leak_profiler();
|
||||
return clear(instance());
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -39,13 +39,14 @@ class JfrStackTraceRepository : public JfrCHeapObj {
|
||||
friend class JfrThreadSampleClosure;
|
||||
friend class ObjectSampleCheckpoint;
|
||||
friend class ObjectSampler;
|
||||
friend class RecordStackTrace;
|
||||
friend class StackTraceBlobInstaller;
|
||||
friend class StackTraceRepository;
|
||||
|
||||
private:
|
||||
static const u4 TABLE_SIZE = 2053;
|
||||
JfrStackTrace* _table[TABLE_SIZE];
|
||||
traceid _next_id;
|
||||
u4 _last_entries;
|
||||
u4 _entries;
|
||||
|
||||
JfrStackTraceRepository();
|
||||
@ -55,18 +56,21 @@ class JfrStackTraceRepository : public JfrCHeapObj {
|
||||
bool initialize();
|
||||
|
||||
bool is_modified() const;
|
||||
static size_t clear();
|
||||
static size_t clear(JfrStackTraceRepository& repo);
|
||||
size_t write(JfrChunkWriter& cw, bool clear);
|
||||
size_t clear();
|
||||
|
||||
const JfrStackTrace* lookup(unsigned int hash, traceid id) const;
|
||||
static const JfrStackTrace* lookup_for_leak_profiler(unsigned int hash, traceid id);
|
||||
static void record_for_leak_profiler(JavaThread* thread, int skip = 0);
|
||||
static void clear_leak_profiler();
|
||||
|
||||
traceid add_trace(const JfrStackTrace& stacktrace);
|
||||
static traceid add(JfrStackTraceRepository& repo, const JfrStackTrace& stacktrace);
|
||||
static traceid add(const JfrStackTrace& stacktrace);
|
||||
traceid record_for(JavaThread* thread, int skip, JfrStackFrame* frames, u4 max_frames);
|
||||
|
||||
public:
|
||||
static traceid record(Thread* thread, int skip = 0);
|
||||
static void record_and_cache(JavaThread* thread, int skip = 0);
|
||||
};
|
||||
|
||||
#endif // SHARE_JFR_RECORDER_STACKTRACE_JFRSTACKTRACEREPOSITORY_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2020, 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
|
||||
@ -26,20 +26,11 @@
|
||||
#include "jfr/leakprofiler/leakProfiler.hpp"
|
||||
#include "jfr/support/jfrAllocationTracer.hpp"
|
||||
#include "jfr/support/jfrObjectAllocationSample.hpp"
|
||||
#include "jfr/support/jfrThreadLocal.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
JfrAllocationTracer::JfrAllocationTracer(const Klass* klass, HeapWord* obj, size_t alloc_size, bool outside_tlab, Thread* thread) : _tl(NULL) {
|
||||
JfrAllocationTracer::JfrAllocationTracer(const Klass* klass, HeapWord* obj, size_t alloc_size, bool outside_tlab, Thread* thread) {
|
||||
if (LeakProfiler::is_running()) {
|
||||
_tl = thread->jfr_thread_local();
|
||||
LeakProfiler::sample(obj, alloc_size, thread->as_Java_thread());
|
||||
}
|
||||
// Let this happen after LeakProfiler::sample, to possibly reuse a cached stacktrace.
|
||||
JfrObjectAllocationSample::send_event(klass, alloc_size, outside_tlab, thread);
|
||||
}
|
||||
|
||||
JfrAllocationTracer::~JfrAllocationTracer() {
|
||||
if (_tl != NULL) {
|
||||
_tl->clear_cached_stack_trace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, 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
|
||||
@ -28,15 +28,11 @@
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class Klass;
|
||||
class JfrThreadLocal;
|
||||
class Thread;
|
||||
|
||||
class JfrAllocationTracer : public StackObj {
|
||||
private:
|
||||
JfrThreadLocal* _tl;
|
||||
public:
|
||||
JfrAllocationTracer(const Klass* klass, HeapWord* obj, size_t alloc_size, bool outside_tlab, Thread* thread);
|
||||
~JfrAllocationTracer();
|
||||
};
|
||||
|
||||
#endif // SHARE_JFR_SUPPORT_JFRALLOCATIONTRACER_HPP
|
||||
|
||||
@ -373,7 +373,14 @@ void* Arena::grow(size_t x, AllocFailType alloc_failmode) {
|
||||
|
||||
// Reallocate storage in Arena.
|
||||
void *Arena::Arealloc(void* old_ptr, size_t old_size, size_t new_size, AllocFailType alloc_failmode) {
|
||||
if (new_size == 0) return NULL;
|
||||
if (new_size == 0) {
|
||||
Afree(old_ptr, old_size); // like realloc(3)
|
||||
return NULL;
|
||||
}
|
||||
if (old_ptr == NULL) {
|
||||
assert(old_size == 0, "sanity");
|
||||
return Amalloc(new_size, alloc_failmode); // as with realloc(3), a NULL old ptr is equivalent to malloc(3)
|
||||
}
|
||||
#ifdef ASSERT
|
||||
if (UseMallocOnly) {
|
||||
// always allocate a new object (otherwise we'll free this one twice)
|
||||
|
||||
@ -186,6 +186,9 @@ protected:
|
||||
|
||||
// Fast delete in area. Common case is: NOP (except for storage reclaimed)
|
||||
bool Afree(void *ptr, size_t size) {
|
||||
if (ptr == NULL) {
|
||||
return true; // as with free(3), freeing NULL is a noop.
|
||||
}
|
||||
#ifdef ASSERT
|
||||
if (ZapResourceArea) memset(ptr, badResourceValue, size); // zap freed memory
|
||||
if (UseMallocOnly) return true;
|
||||
|
||||
@ -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
|
||||
@ -4240,7 +4240,8 @@ void InstanceKlass::log_to_classlist(const ClassFileStream* stream) const {
|
||||
// For the boot and platform class loaders, skip classes that are not found in the
|
||||
// java runtime image, such as those found in the --patch-module entries.
|
||||
// These classes can't be loaded from the archive during runtime.
|
||||
if (!stream->from_boot_loader_modules_image() && strncmp(stream->source(), "jrt:", 4) != 0) {
|
||||
if (!stream->from_boot_loader_modules_image() &&
|
||||
(stream->source() == NULL || strncmp(stream->source(), "jrt:", 4) != 0)) {
|
||||
skip = true;
|
||||
}
|
||||
|
||||
@ -4254,7 +4255,8 @@ void InstanceKlass::log_to_classlist(const ClassFileStream* stream) const {
|
||||
ResourceMark rm;
|
||||
if (skip) {
|
||||
tty->print_cr("skip writing class %s from source %s to classlist file",
|
||||
name()->as_C_string(), stream->source());
|
||||
name()->as_C_string(),
|
||||
stream->source() != NULL ? stream->source() : "(null)");
|
||||
} else {
|
||||
ClassListWriter w;
|
||||
w.stream()->print_cr("%s", name()->as_C_string());
|
||||
|
||||
@ -532,7 +532,30 @@ bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1,
|
||||
Node* LoadNode::find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, Node*& mem, bool can_see_stored_value) const {
|
||||
ArrayCopyNode* ac = find_array_copy_clone(phase, ld_alloc, mem);
|
||||
if (ac != NULL) {
|
||||
return ac;
|
||||
Node* ld_addp = in(MemNode::Address);
|
||||
Node* src = ac->in(ArrayCopyNode::Src);
|
||||
const TypeAryPtr* ary_t = phase->type(src)->isa_aryptr();
|
||||
|
||||
// This is a load from a cloned array. The corresponding arraycopy ac must
|
||||
// have set the value for the load and we can return ac but only if the load
|
||||
// is known to be within bounds. This is checked below.
|
||||
if (ary_t != NULL && ld_addp->is_AddP()) {
|
||||
Node* ld_offs = ld_addp->in(AddPNode::Offset);
|
||||
BasicType ary_elem = ary_t->klass()->as_array_klass()->element_type()->basic_type();
|
||||
jlong header = arrayOopDesc::base_offset_in_bytes(ary_elem);
|
||||
jlong elemsize = type2aelembytes(ary_elem);
|
||||
|
||||
const TypeX* ld_offs_t = phase->type(ld_offs)->isa_intptr_t();
|
||||
const TypeInt* sizetype = ary_t->size();
|
||||
|
||||
if (ld_offs_t->_lo >= header && ld_offs_t->_hi < (sizetype->_lo * elemsize + header)) {
|
||||
// The load is known to be within bounds. It receives its value from ac.
|
||||
return ac;
|
||||
}
|
||||
// The load is known to be out-of-bounds.
|
||||
}
|
||||
// The load could be out-of-bounds. It must not be hoisted but must remain
|
||||
// dependent on the runtime range check. This is achieved by returning NULL.
|
||||
} else if (mem->is_Proj() && mem->in(0) != NULL && mem->in(0)->is_ArrayCopy()) {
|
||||
ArrayCopyNode* ac = mem->in(0)->as_ArrayCopy();
|
||||
|
||||
|
||||
@ -1149,6 +1149,11 @@ Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
|
||||
int arg_val = arg->get_int();
|
||||
int count = 1;
|
||||
if (arg_val < 0) {
|
||||
// Special case for min_jint - it can't be negated.
|
||||
if (arg_val == min_jint) {
|
||||
return __ intcon(11);
|
||||
}
|
||||
|
||||
arg_val = -arg_val;
|
||||
count++;
|
||||
}
|
||||
|
||||
@ -1203,15 +1203,15 @@ JvmtiEnv::GetOwnedMonitorInfo(JavaThread* java_thread, jint* owned_monitor_count
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
JavaThread* calling_thread = JavaThread::current();
|
||||
|
||||
// growable array of jvmti monitors info on the C-heap
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
|
||||
new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
|
||||
|
||||
EscapeBarrier eb(true, calling_thread, java_thread);
|
||||
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
|
||||
return JVMTI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// growable array of jvmti monitors info on the C-heap
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
|
||||
new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
|
||||
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a direct handshake for safety.
|
||||
if (java_thread == calling_thread) {
|
||||
@ -1253,15 +1253,15 @@ JvmtiEnv::GetOwnedMonitorStackDepthInfo(JavaThread* java_thread, jint* monitor_i
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
JavaThread* calling_thread = JavaThread::current();
|
||||
|
||||
// growable array of jvmti monitors info on the C-heap
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
|
||||
new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
|
||||
|
||||
EscapeBarrier eb(true, calling_thread, java_thread);
|
||||
if (!eb.deoptimize_objects(MaxJavaStackTraceDepth)) {
|
||||
return JVMTI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// growable array of jvmti monitors info on the C-heap
|
||||
GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
|
||||
new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, mtServiceability);
|
||||
|
||||
// It is only safe to perform the direct operation on the current
|
||||
// thread. All other usage needs to use a direct handshake for safety.
|
||||
if (java_thread == calling_thread) {
|
||||
|
||||
@ -259,19 +259,16 @@ class GetCurrentLocationClosure : public HandshakeClosure {
|
||||
JavaThread *jt = target->as_Java_thread();
|
||||
ResourceMark rmark; // jt != Thread::current()
|
||||
RegisterMap rm(jt, false);
|
||||
// There can be a race condition between a VM_Operation reaching a safepoint
|
||||
// There can be a race condition between a handshake
|
||||
// and the target thread exiting from Java execution.
|
||||
// We must recheck the last Java frame still exists.
|
||||
// We must recheck that the last Java frame still exists.
|
||||
if (!jt->is_exiting() && jt->has_last_Java_frame()) {
|
||||
javaVFrame* vf = jt->last_java_vframe(&rm);
|
||||
assert(vf != NULL, "must have last java frame");
|
||||
Method* method = vf->method();
|
||||
_method_id = method->jmethod_id();
|
||||
_bci = vf->bci();
|
||||
} else {
|
||||
// Clear current location as the target thread has no Java frames anymore.
|
||||
_method_id = (jmethodID)NULL;
|
||||
_bci = 0;
|
||||
if (vf != NULL) {
|
||||
Method* method = vf->method();
|
||||
_method_id = method->jmethod_id();
|
||||
_bci = vf->bci();
|
||||
}
|
||||
}
|
||||
_completed = true;
|
||||
}
|
||||
|
||||
@ -407,7 +407,7 @@ class Thread: public ThreadShadow {
|
||||
|
||||
JFR_ONLY(DEFINE_THREAD_LOCAL_FIELD_JFR;) // Thread-local data for jfr
|
||||
|
||||
ObjectMonitor* _current_pending_monitor; // ObjectMonitor this thread
|
||||
ObjectMonitor* volatile _current_pending_monitor; // ObjectMonitor this thread
|
||||
// is waiting to lock
|
||||
bool _current_pending_monitor_is_from_java; // locking is from Java code
|
||||
JvmtiRawMonitor* _current_pending_raw_monitor; // JvmtiRawMonitor this thread
|
||||
@ -415,7 +415,7 @@ class Thread: public ThreadShadow {
|
||||
|
||||
|
||||
// ObjectMonitor on which this thread called Object.wait()
|
||||
ObjectMonitor* _current_waiting_monitor;
|
||||
ObjectMonitor* volatile _current_waiting_monitor;
|
||||
|
||||
#ifdef ASSERT
|
||||
private:
|
||||
@ -620,10 +620,13 @@ class Thread: public ThreadShadow {
|
||||
|
||||
// For tracking the heavyweight monitor the thread is pending on.
|
||||
ObjectMonitor* current_pending_monitor() {
|
||||
return _current_pending_monitor;
|
||||
// Use Atomic::load() to prevent data race between concurrent modification and
|
||||
// concurrent readers, e.g. ThreadService::get_current_contended_monitor().
|
||||
// Especially, reloading pointer from thread after NULL check must be prevented.
|
||||
return Atomic::load(&_current_pending_monitor);
|
||||
}
|
||||
void set_current_pending_monitor(ObjectMonitor* monitor) {
|
||||
_current_pending_monitor = monitor;
|
||||
Atomic::store(&_current_pending_monitor, monitor);
|
||||
}
|
||||
void set_current_pending_monitor_is_from_java(bool from_java) {
|
||||
_current_pending_monitor_is_from_java = from_java;
|
||||
@ -634,10 +637,11 @@ class Thread: public ThreadShadow {
|
||||
|
||||
// For tracking the ObjectMonitor on which this thread called Object.wait()
|
||||
ObjectMonitor* current_waiting_monitor() {
|
||||
return _current_waiting_monitor;
|
||||
// See the comment in current_pending_monitor() above.
|
||||
return Atomic::load(&_current_waiting_monitor);
|
||||
}
|
||||
void set_current_waiting_monitor(ObjectMonitor* monitor) {
|
||||
_current_waiting_monitor = monitor;
|
||||
Atomic::store(&_current_waiting_monitor, monitor);
|
||||
}
|
||||
|
||||
// For tracking the Jvmti raw monitor the thread is pending on.
|
||||
|
||||
@ -738,9 +738,9 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
nonstatic_field(Thread, _active_handles, JNIHandleBlock*) \
|
||||
nonstatic_field(Thread, _tlab, ThreadLocalAllocBuffer) \
|
||||
nonstatic_field(Thread, _allocated_bytes, jlong) \
|
||||
nonstatic_field(Thread, _current_pending_monitor, ObjectMonitor*) \
|
||||
volatile_nonstatic_field(Thread, _current_pending_monitor, ObjectMonitor*) \
|
||||
nonstatic_field(Thread, _current_pending_monitor_is_from_java, bool) \
|
||||
nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \
|
||||
volatile_nonstatic_field(Thread, _current_waiting_monitor, ObjectMonitor*) \
|
||||
nonstatic_field(NamedThread, _name, char*) \
|
||||
nonstatic_field(NamedThread, _processed_thread, Thread*) \
|
||||
nonstatic_field(JavaThread, _threadObj, OopHandle) \
|
||||
|
||||
@ -379,22 +379,20 @@ class Command : public StackObj {
|
||||
|
||||
int Command::level = 0;
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
extern "C" void blob(CodeBlob* cb) {
|
||||
extern "C" JNIEXPORT void blob(CodeBlob* cb) {
|
||||
Command c("blob");
|
||||
cb->print();
|
||||
}
|
||||
|
||||
|
||||
extern "C" void dump_vtable(address p) {
|
||||
extern "C" JNIEXPORT void dump_vtable(address p) {
|
||||
Command c("dump_vtable");
|
||||
Klass* k = (Klass*)p;
|
||||
k->vtable().print();
|
||||
}
|
||||
|
||||
|
||||
extern "C" void nm(intptr_t p) {
|
||||
extern "C" JNIEXPORT void nm(intptr_t p) {
|
||||
// Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
|
||||
Command c("nm");
|
||||
CodeBlob* cb = CodeCache::find_blob((address)p);
|
||||
@ -406,7 +404,7 @@ extern "C" void nm(intptr_t p) {
|
||||
}
|
||||
|
||||
|
||||
extern "C" void disnm(intptr_t p) {
|
||||
extern "C" JNIEXPORT void disnm(intptr_t p) {
|
||||
Command c("disnm");
|
||||
CodeBlob* cb = CodeCache::find_blob((address) p);
|
||||
if (cb != NULL) {
|
||||
@ -421,7 +419,7 @@ extern "C" void disnm(intptr_t p) {
|
||||
}
|
||||
|
||||
|
||||
extern "C" void printnm(intptr_t p) {
|
||||
extern "C" JNIEXPORT void printnm(intptr_t p) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
|
||||
Command c(buffer);
|
||||
@ -433,13 +431,13 @@ extern "C" void printnm(intptr_t p) {
|
||||
}
|
||||
|
||||
|
||||
extern "C" void universe() {
|
||||
extern "C" JNIEXPORT void universe() {
|
||||
Command c("universe");
|
||||
Universe::print_on(tty);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void verify() {
|
||||
extern "C" JNIEXPORT void verify() {
|
||||
// try to run a verify on the entire system
|
||||
// note: this may not be safe if we're not at a safepoint; for debugging,
|
||||
// this manipulates the safepoint settings to avoid assertion failures
|
||||
@ -456,7 +454,7 @@ extern "C" void verify() {
|
||||
}
|
||||
|
||||
|
||||
extern "C" void pp(void* p) {
|
||||
extern "C" JNIEXPORT void pp(void* p) {
|
||||
Command c("pp");
|
||||
FlagSetting fl(DisplayVMOutput, true);
|
||||
if (Universe::heap()->is_in(p)) {
|
||||
@ -468,17 +466,12 @@ extern "C" void pp(void* p) {
|
||||
}
|
||||
|
||||
|
||||
// pv: print vm-printable object
|
||||
extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
|
||||
extern "C" void findpc(intptr_t x);
|
||||
extern "C" JNIEXPORT void findpc(intptr_t x);
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
||||
extern "C" void ps() { // print stack
|
||||
extern "C" JNIEXPORT void ps() { // print stack
|
||||
if (Thread::current_or_null() == NULL) return;
|
||||
Command c("ps");
|
||||
|
||||
|
||||
// Prints the stack of the current Java thread
|
||||
JavaThread* p = JavaThread::active();
|
||||
tty->print(" for thread: ");
|
||||
@ -506,7 +499,7 @@ extern "C" void ps() { // print stack
|
||||
|
||||
}
|
||||
|
||||
extern "C" void pfl() {
|
||||
extern "C" JNIEXPORT void pfl() {
|
||||
// print frame layout
|
||||
Command c("pfl");
|
||||
JavaThread* p = JavaThread::active();
|
||||
@ -518,9 +511,7 @@ extern "C" void pfl() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
extern "C" void psf() { // print stack frames
|
||||
extern "C" JNIEXPORT void psf() { // print stack frames
|
||||
{
|
||||
Command c("psf");
|
||||
JavaThread* p = JavaThread::active();
|
||||
@ -534,37 +525,36 @@ extern "C" void psf() { // print stack frames
|
||||
}
|
||||
|
||||
|
||||
extern "C" void threads() {
|
||||
extern "C" JNIEXPORT void threads() {
|
||||
Command c("threads");
|
||||
Threads::print(false, true);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void psd() {
|
||||
extern "C" JNIEXPORT void psd() {
|
||||
Command c("psd");
|
||||
SystemDictionary::print();
|
||||
}
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
||||
extern "C" void pss() { // print all stacks
|
||||
extern "C" JNIEXPORT void pss() { // print all stacks
|
||||
if (Thread::current_or_null() == NULL) return;
|
||||
Command c("pss");
|
||||
Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
// #ifndef PRODUCT
|
||||
|
||||
extern "C" void debug() { // to set things up for compiler debugging
|
||||
extern "C" JNIEXPORT void debug() { // to set things up for compiler debugging
|
||||
Command c("debug");
|
||||
WizardMode = true;
|
||||
NOT_PRODUCT(WizardMode = true;)
|
||||
PrintCompilation = true;
|
||||
PrintInlining = PrintAssembly = true;
|
||||
tty->flush();
|
||||
}
|
||||
|
||||
|
||||
extern "C" void ndebug() { // undo debug()
|
||||
extern "C" JNIEXPORT void ndebug() { // undo debug()
|
||||
Command c("ndebug");
|
||||
PrintCompilation = false;
|
||||
PrintInlining = PrintAssembly = false;
|
||||
@ -572,50 +562,50 @@ extern "C" void ndebug() { // undo debug()
|
||||
}
|
||||
|
||||
|
||||
extern "C" void flush() {
|
||||
extern "C" JNIEXPORT void flush() {
|
||||
Command c("flush");
|
||||
tty->flush();
|
||||
}
|
||||
|
||||
extern "C" void events() {
|
||||
extern "C" JNIEXPORT void events() {
|
||||
Command c("events");
|
||||
Events::print();
|
||||
}
|
||||
|
||||
extern "C" Method* findm(intptr_t pc) {
|
||||
extern "C" JNIEXPORT Method* findm(intptr_t pc) {
|
||||
Command c("findm");
|
||||
nmethod* nm = CodeCache::find_nmethod((address)pc);
|
||||
return (nm == NULL) ? (Method*)NULL : nm->method();
|
||||
}
|
||||
|
||||
|
||||
extern "C" nmethod* findnm(intptr_t addr) {
|
||||
extern "C" JNIEXPORT nmethod* findnm(intptr_t addr) {
|
||||
Command c("findnm");
|
||||
return CodeCache::find_nmethod((address)addr);
|
||||
}
|
||||
|
||||
// Another interface that isn't ambiguous in dbx.
|
||||
// Can we someday rename the other find to hsfind?
|
||||
extern "C" void hsfind(intptr_t x) {
|
||||
extern "C" JNIEXPORT void hsfind(intptr_t x) {
|
||||
Command c("hsfind");
|
||||
os::print_location(tty, x, false);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void find(intptr_t x) {
|
||||
extern "C" JNIEXPORT void find(intptr_t x) {
|
||||
Command c("find");
|
||||
os::print_location(tty, x, false);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void findpc(intptr_t x) {
|
||||
extern "C" JNIEXPORT void findpc(intptr_t x) {
|
||||
Command c("findpc");
|
||||
os::print_location(tty, x, true);
|
||||
}
|
||||
|
||||
|
||||
// Need method pointer to find bcp, when not in permgen.
|
||||
extern "C" void findbcp(intptr_t method, intptr_t bcp) {
|
||||
extern "C" JNIEXPORT void findbcp(intptr_t method, intptr_t bcp) {
|
||||
Command c("findbcp");
|
||||
Method* mh = (Method*)method;
|
||||
if (!mh->is_native()) {
|
||||
@ -634,7 +624,6 @@ void help() {
|
||||
Command c("help");
|
||||
tty->print_cr("basic");
|
||||
tty->print_cr(" pp(void* p) - try to make sense of p");
|
||||
tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
|
||||
tty->print_cr(" ps() - print current thread stack");
|
||||
tty->print_cr(" pss() - print all thread stacks");
|
||||
tty->print_cr(" pm(int pc) - print Method* given compiled PC");
|
||||
@ -659,7 +648,8 @@ void help() {
|
||||
tty->print_cr(" ndebug() - undo debug");
|
||||
}
|
||||
|
||||
extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack
|
||||
#ifndef PRODUCT
|
||||
extern "C" JNIEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack
|
||||
Command c("pns");
|
||||
static char buf[O_BUFLEN];
|
||||
Thread* t = Thread::current_or_null();
|
||||
@ -676,7 +666,7 @@ extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack
|
||||
// WARNING: Only intended for use when debugging. Do not leave calls to
|
||||
// pns2() in committed source (product or debug).
|
||||
//
|
||||
extern "C" void pns2() { // print native stack
|
||||
extern "C" JNIEXPORT void pns2() { // print native stack
|
||||
Command c("pns2");
|
||||
static char buf[O_BUFLEN];
|
||||
if (os::platform_print_native_stack(tty, NULL, buf, sizeof(buf))) {
|
||||
@ -688,8 +678,8 @@ extern "C" void pns2() { // print native stack
|
||||
VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !PRODUCT
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Test multiple STATIC_ASSERT forms in various scopes.
|
||||
|
||||
@ -1381,13 +1381,14 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
|
||||
static bool out_done = false; // done printing to standard out
|
||||
static bool log_done = false; // done saving error log
|
||||
|
||||
if (SuppressFatalErrorMessage) {
|
||||
os::abort(CreateCoredumpOnCrash);
|
||||
}
|
||||
intptr_t mytid = os::current_thread_id();
|
||||
if (_first_error_tid == -1 &&
|
||||
Atomic::cmpxchg(&_first_error_tid, (intptr_t)-1, mytid) == -1) {
|
||||
|
||||
if (SuppressFatalErrorMessage) {
|
||||
os::abort(CreateCoredumpOnCrash);
|
||||
}
|
||||
|
||||
// Initialize time stamps to use the same base.
|
||||
out.time_stamp().update_to(1);
|
||||
log.time_stamp().update_to(1);
|
||||
@ -1440,21 +1441,33 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
|
||||
// This is not the first error, see if it happened in a different thread
|
||||
// or in the same thread during error reporting.
|
||||
if (_first_error_tid != mytid) {
|
||||
char msgbuf[64];
|
||||
jio_snprintf(msgbuf, sizeof(msgbuf),
|
||||
"[thread " INTX_FORMAT " also had an error]",
|
||||
mytid);
|
||||
out.print_raw_cr(msgbuf);
|
||||
if (!SuppressFatalErrorMessage) {
|
||||
char msgbuf[64];
|
||||
jio_snprintf(msgbuf, sizeof(msgbuf),
|
||||
"[thread " INTX_FORMAT " also had an error]",
|
||||
mytid);
|
||||
out.print_raw_cr(msgbuf);
|
||||
}
|
||||
|
||||
// error reporting is not MT-safe, block current thread
|
||||
// Error reporting is not MT-safe, nor can we let the current thread
|
||||
// proceed, so we block it.
|
||||
os::infinite_sleep();
|
||||
|
||||
} else {
|
||||
if (recursive_error_count++ > 30) {
|
||||
out.print_raw_cr("[Too many errors, abort]");
|
||||
if (!SuppressFatalErrorMessage) {
|
||||
out.print_raw_cr("[Too many errors, abort]");
|
||||
}
|
||||
os::die();
|
||||
}
|
||||
|
||||
if (SuppressFatalErrorMessage) {
|
||||
// If we already hit a secondary error during abort, then calling
|
||||
// it again is likely to hit another one. But eventually, if we
|
||||
// don't deadlock somewhere, we will call os::die() above.
|
||||
os::abort(CreateCoredumpOnCrash);
|
||||
}
|
||||
|
||||
outputStream* const st = log.is_open() ? &log : &out;
|
||||
st->cr();
|
||||
|
||||
|
||||
@ -225,6 +225,7 @@ public class ZipFile implements ZipConstants, Closeable {
|
||||
Integer.toHexString(mode));
|
||||
}
|
||||
String name = file.getPath();
|
||||
file = new File(name);
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkRead(name);
|
||||
|
||||
@ -538,6 +538,9 @@ public class ClassReader {
|
||||
} else if (Constants.SYNTHETIC.equals(attributeName)) {
|
||||
accessFlags |= Opcodes.ACC_SYNTHETIC;
|
||||
} else if (Constants.SOURCE_DEBUG_EXTENSION.equals(attributeName)) {
|
||||
if (attributeLength > classFileBuffer.length - currentAttributeOffset) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
sourceDebugExtension =
|
||||
readUtf(currentAttributeOffset, attributeLength, new char[attributeLength]);
|
||||
} else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) {
|
||||
@ -1548,6 +1551,9 @@ public class ClassReader {
|
||||
final int maxLocals = readUnsignedShort(currentOffset + 2);
|
||||
final int codeLength = readInt(currentOffset + 4);
|
||||
currentOffset += 8;
|
||||
if (codeLength > classFileBuffer.length - currentOffset) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
// Read the bytecode 'code' array to create a label for each referenced instruction.
|
||||
final int bytecodeStartOffset = currentOffset;
|
||||
|
||||
@ -24,16 +24,36 @@
|
||||
*/
|
||||
package sun.net.ftp.impl;
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.Closeable;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.text.DateFormat;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
@ -44,7 +64,11 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import sun.net.ftp.*;
|
||||
import sun.net.ftp.FtpDirEntry;
|
||||
import sun.net.ftp.FtpDirParser;
|
||||
import sun.net.ftp.FtpProtocolException;
|
||||
import sun.net.ftp.FtpReplyCode;
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
|
||||
@ -107,15 +131,16 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
private static Pattern[] patterns;
|
||||
private static Pattern linkp = Pattern.compile("(\\p{Print}+) \\-\\> (\\p{Print}+)$");
|
||||
private DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, java.util.Locale.US);
|
||||
|
||||
private static final boolean acceptPasvAddressVal;
|
||||
static {
|
||||
final int vals[] = {0, 0};
|
||||
final String encs[] = {null};
|
||||
|
||||
final String acceptPasvAddress[] = {null};
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<Object>() {
|
||||
|
||||
public Object run() {
|
||||
acceptPasvAddress[0] = System.getProperty("jdk.net.ftp.trustPasvAddress", "false");
|
||||
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
|
||||
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
|
||||
encs[0] = System.getProperty("file.encoding", "ISO8859_1");
|
||||
@ -147,6 +172,8 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
for (int i = 0; i < patStrings.length; i++) {
|
||||
patterns[i] = Pattern.compile(patStrings[i]);
|
||||
}
|
||||
|
||||
acceptPasvAddressVal = Boolean.parseBoolean(acceptPasvAddress[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -613,7 +640,6 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
//
|
||||
// The regular expression is a bit more complex this time, because
|
||||
// the parenthesis are optionals and we have to use 3 groups.
|
||||
|
||||
if (pasvPat == null) {
|
||||
pasvPat = Pattern.compile("227 .* \\(?(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)?");
|
||||
}
|
||||
@ -625,8 +651,15 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
port = Integer.parseInt(m.group(3)) + (Integer.parseInt(m.group(2)) << 8);
|
||||
// IP address is simple
|
||||
String s = m.group(1).replace(',', '.');
|
||||
dest = new InetSocketAddress(s, port);
|
||||
if (!IPAddressUtil.isIPv4LiteralAddress(s))
|
||||
throw new FtpProtocolException("PASV failed : " + serverAnswer);
|
||||
if (acceptPasvAddressVal) {
|
||||
dest = new InetSocketAddress(s, port);
|
||||
} else {
|
||||
dest = validatePasvAddress(port, s, server.getInetAddress());
|
||||
}
|
||||
}
|
||||
|
||||
// Got everything, let's open the socket!
|
||||
Socket s;
|
||||
if (proxy != null) {
|
||||
@ -688,6 +721,76 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
return s;
|
||||
}
|
||||
|
||||
static final String ERROR_MSG = "Address should be the same as originating server";
|
||||
|
||||
/**
|
||||
* Returns an InetSocketAddress, based on value of acceptPasvAddressVal
|
||||
* and other conditions such as the server address returned by pasv
|
||||
* is not a hostname, is a socks proxy, or the loopback. An exception
|
||||
* is thrown if none of the valid conditions are met.
|
||||
*/
|
||||
private InetSocketAddress validatePasvAddress(int port, String s, InetAddress address)
|
||||
throws FtpProtocolException
|
||||
{
|
||||
if (address == null) {
|
||||
return InetSocketAddress.createUnresolved(serverAddr.getHostName(), port);
|
||||
}
|
||||
String serverAddress = address.getHostAddress();
|
||||
if (serverAddress.equals(s)) {
|
||||
return new InetSocketAddress(s, port);
|
||||
} else if (address.isLoopbackAddress() && s.startsWith("127.")) { // can be 127.0
|
||||
return new InetSocketAddress(s, port);
|
||||
} else if (address.isLoopbackAddress()) {
|
||||
if (privilegedLocalHost().getHostAddress().equals(s)) {
|
||||
return new InetSocketAddress(s, port);
|
||||
} else {
|
||||
throw new FtpProtocolException(ERROR_MSG);
|
||||
}
|
||||
} else if (s.startsWith("127.")) {
|
||||
if (privilegedLocalHost().equals(address)) {
|
||||
return new InetSocketAddress(s, port);
|
||||
} else {
|
||||
throw new FtpProtocolException(ERROR_MSG);
|
||||
}
|
||||
}
|
||||
String hostName = address.getHostName();
|
||||
if (!(IPAddressUtil.isIPv4LiteralAddress(hostName) || IPAddressUtil.isIPv6LiteralAddress(hostName))) {
|
||||
InetAddress[] names = privilegedGetAllByName(hostName);
|
||||
String resAddress = Arrays
|
||||
.stream(names)
|
||||
.map(InetAddress::getHostAddress)
|
||||
.filter(s::equalsIgnoreCase)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (resAddress != null) {
|
||||
return new InetSocketAddress(s, port);
|
||||
}
|
||||
}
|
||||
throw new FtpProtocolException(ERROR_MSG);
|
||||
}
|
||||
|
||||
private static InetAddress privilegedLocalHost() throws FtpProtocolException {
|
||||
PrivilegedExceptionAction<InetAddress> action = InetAddress::getLocalHost;
|
||||
try {
|
||||
return AccessController.doPrivileged(action);
|
||||
} catch (Exception e) {
|
||||
var ftpEx = new FtpProtocolException(ERROR_MSG);
|
||||
ftpEx.initCause(e);
|
||||
throw ftpEx;
|
||||
}
|
||||
}
|
||||
|
||||
private static InetAddress[] privilegedGetAllByName(String hostName) throws FtpProtocolException {
|
||||
PrivilegedExceptionAction<InetAddress[]> pAction = () -> InetAddress.getAllByName(hostName);
|
||||
try {
|
||||
return AccessController.doPrivileged(pAction);
|
||||
} catch (Exception e) {
|
||||
var ftpEx = new FtpProtocolException(ERROR_MSG);
|
||||
ftpEx.initCause(e);
|
||||
throw ftpEx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a data connection with the server according to the set mode
|
||||
* (ACTIVE or PASSIVE) then send the command passed as an argument.
|
||||
@ -698,7 +801,6 @@ public class FtpClient extends sun.net.ftp.FtpClient {
|
||||
*/
|
||||
private Socket openDataConnection(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
|
||||
Socket clientSocket;
|
||||
|
||||
if (passiveMode) {
|
||||
try {
|
||||
return openPassiveDataConnection(cmd);
|
||||
|
||||
@ -331,7 +331,18 @@ public class SignerInfo implements DerEncoder {
|
||||
throws NoSuchAlgorithmException, SignatureException {
|
||||
|
||||
try {
|
||||
Timestamp timestamp = getTimestamp();
|
||||
Timestamp timestamp = null;
|
||||
try {
|
||||
timestamp = getTimestamp();
|
||||
} catch (Exception e) {
|
||||
// Log exception and continue. This allows for the case
|
||||
// where, if there are no other errors, the code is
|
||||
// signed but w/o a timestamp.
|
||||
if (debug != null) {
|
||||
debug.println("Unexpected exception while getting" +
|
||||
" timestamp: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
ContentInfo content = block.getContentInfo();
|
||||
if (data == null) {
|
||||
@ -471,7 +482,7 @@ public class SignerInfo implements DerEncoder {
|
||||
if (sig.verify(encryptedDigest)) {
|
||||
return this;
|
||||
}
|
||||
} catch (IOException | CertificateException e) {
|
||||
} catch (IOException e) {
|
||||
throw new SignatureException("Error verifying signature", e);
|
||||
}
|
||||
return null;
|
||||
|
||||
@ -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
|
||||
@ -43,13 +43,15 @@ import sun.security.rsa.RSAUtil.KeyType;
|
||||
* 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
|
||||
@ -95,8 +97,8 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||
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))) {
|
||||
@ -265,14 +267,10 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,15 +307,9 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,11 +317,8 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||
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 {
|
||||
@ -351,11 +340,8 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||
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 {
|
||||
@ -395,7 +381,8 @@ public class RSAKeyFactory extends KeyFactorySpi {
|
||||
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);
|
||||
|
||||
@ -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
|
||||
@ -74,30 +74,52 @@ public final class RSAPrivateCrtKeyImpl
|
||||
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 {
|
||||
public static RSAPrivateKey newKey(KeyType type, String format,
|
||||
byte[] encoded) throws InvalidKeyException {
|
||||
if (encoded == null || encoded.length == 0) {
|
||||
throw new InvalidKeyException("Missing key encoding");
|
||||
}
|
||||
RSAPrivateCrtKeyImpl key = new RSAPrivateCrtKeyImpl(encoded);
|
||||
// check all CRT-specific components are available, if any one
|
||||
// missing, return a non-CRT key instead
|
||||
if ((key.getPublicExponent().signum() == 0) ||
|
||||
(key.getPrimeExponentP().signum() == 0) ||
|
||||
(key.getPrimeExponentQ().signum() == 0) ||
|
||||
(key.getPrimeP().signum() == 0) ||
|
||||
(key.getPrimeQ().signum() == 0) ||
|
||||
(key.getCrtCoefficient().signum() == 0)) {
|
||||
return new RSAPrivateKeyImpl(
|
||||
key.type, key.keyParams,
|
||||
key.getModulus(),
|
||||
key.getPrivateExponent()
|
||||
);
|
||||
} else {
|
||||
return key;
|
||||
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 ((key.getPublicExponent().signum() == 0) ||
|
||||
(key.getPrimeExponentP().signum() == 0) ||
|
||||
(key.getPrimeExponentQ().signum() == 0) ||
|
||||
(key.getPrimeP().signum() == 0) ||
|
||||
(key.getPrimeQ().signum() == 0) ||
|
||||
(key.getCrtCoefficient().signum() == 0)) {
|
||||
return new RSAPrivateKeyImpl(key.type, key.keyParams,
|
||||
key.getModulus(), key.getPrivateExponent());
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,7 +148,7 @@ public final class RSAPrivateCrtKeyImpl
|
||||
/**
|
||||
* Construct a key from its encoding. Called from newKey above.
|
||||
*/
|
||||
RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
|
||||
private RSAPrivateCrtKeyImpl(byte[] encoded) throws InvalidKeyException {
|
||||
super(encoded);
|
||||
parseKeyBits();
|
||||
RSAKeyFactory.checkRSAProviderKeyLengths(n.bitLength(), e);
|
||||
@ -258,37 +280,47 @@ public final class RSAPrivateCrtKeyImpl
|
||||
+ "\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;
|
||||
}
|
||||
|
||||
private 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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -66,17 +66,36 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||
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)
|
||||
@ -123,9 +142,9 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
@ -181,22 +200,30 @@ public final class RSAPublicKeyImpl extends X509Key implements RSAPublicKey {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -271,7 +271,7 @@ final class DTLSOutputRecord extends OutputRecord implements DTLSRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion + " " +
|
||||
"WRITE: " + protocolVersion.name + " " +
|
||||
ContentType.APPLICATION_DATA.name +
|
||||
", length = " + destination.remaining());
|
||||
}
|
||||
@ -499,7 +499,7 @@ final class DTLSOutputRecord extends OutputRecord implements DTLSRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion + " " +
|
||||
"WRITE: " + protocolVersion.name + " " +
|
||||
ContentType.nameOf(memo.contentType) +
|
||||
", length = " + dstBuf.remaining());
|
||||
}
|
||||
|
||||
@ -297,13 +297,13 @@ abstract class HandshakeContext implements ConnectionContext {
|
||||
} else if (SSLLogger.isOn && SSLLogger.isOn("verbose")) {
|
||||
SSLLogger.fine(
|
||||
"Ignore unsupported cipher suite: " + suite +
|
||||
" for " + protocol);
|
||||
" for " + protocol.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && (SSLLogger.isOn) && SSLLogger.isOn("handshake")) {
|
||||
SSLLogger.fine(
|
||||
"No available cipher suite for " + protocol);
|
||||
"No available cipher suite for " + protocol.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -372,9 +372,11 @@ final class PreSharedKeyExtension {
|
||||
SSLSessionImpl s = null;
|
||||
|
||||
for (PskIdentity requestedId : pskSpec.identities) {
|
||||
// If we are keeping state, see if the identity is in the cache
|
||||
// If we are keeping state, see if the identity is in the
|
||||
// cache. Note that for TLS 1.3, we would also clean
|
||||
// up the cached session if it is not rejoinable.
|
||||
if (requestedId.identity.length == SessionId.MAX_LENGTH) {
|
||||
s = sessionCache.get(requestedId.identity);
|
||||
s = sessionCache.pull(requestedId.identity);
|
||||
}
|
||||
// See if the identity is a stateless ticket
|
||||
if (s == null &&
|
||||
|
||||
@ -269,7 +269,7 @@ final class SSLEngineOutputRecord extends OutputRecord implements SSLRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion + " " +
|
||||
"WRITE: " + protocolVersion.name + " " +
|
||||
ContentType.APPLICATION_DATA.name +
|
||||
", length = " + destination.remaining());
|
||||
}
|
||||
@ -508,7 +508,7 @@ final class SSLEngineOutputRecord extends OutputRecord implements SSLRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion + " " +
|
||||
"WRITE: " + protocolVersion.name + " " +
|
||||
ContentType.nameOf(memo.contentType) +
|
||||
", length = " + dstBuf.remaining());
|
||||
}
|
||||
|
||||
@ -175,6 +175,15 @@ final class SSLSessionContextImpl implements SSLSessionContext {
|
||||
return (SSLSessionImpl)getSession(id);
|
||||
}
|
||||
|
||||
// package-private method, find and remove session from cache
|
||||
// return found session
|
||||
SSLSessionImpl pull(byte[] id) {
|
||||
if (id != null) {
|
||||
return sessionCache.pull(new SessionId(id));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// package-private method, used ONLY by ClientHandshaker
|
||||
SSLSessionImpl get(String hostname, int port) {
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 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
|
||||
@ -75,6 +75,16 @@ import jdk.internal.access.SharedSecrets;
|
||||
public final class SSLSocketImpl
|
||||
extends BaseSSLSocketImpl implements SSLTransport {
|
||||
|
||||
/**
|
||||
* ERROR HANDLING GUIDELINES
|
||||
* (which exceptions to throw and catch and which not to throw and catch)
|
||||
*
|
||||
* - if there is an IOException (SocketException) when accessing the
|
||||
* underlying Socket, pass it through
|
||||
*
|
||||
* - do not throw IOExceptions, throw SSLExceptions (or a subclass)
|
||||
*/
|
||||
|
||||
final SSLContextImpl sslContext;
|
||||
final TransportContext conContext;
|
||||
|
||||
@ -447,6 +457,8 @@ public final class SSLSocketImpl
|
||||
throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Couldn't kickstart handshaking", iioe);
|
||||
}
|
||||
} catch (SocketException se) {
|
||||
handleException(se);
|
||||
} catch (IOException ioe) {
|
||||
throw conContext.fatal(Alert.HANDSHAKE_FAILURE,
|
||||
"Couldn't kickstart handshaking", ioe);
|
||||
@ -1406,11 +1418,9 @@ public final class SSLSocketImpl
|
||||
conContext.isNegotiated) {
|
||||
return 0;
|
||||
}
|
||||
} catch (SSLException ssle) {
|
||||
throw ssle;
|
||||
} catch (InterruptedIOException iioe) {
|
||||
// don't change exception in case of timeouts or interrupts
|
||||
throw iioe;
|
||||
} catch (SSLException | InterruptedIOException | SocketException se) {
|
||||
// don't change exception in case of timeouts or interrupts or SocketException
|
||||
throw se;
|
||||
} catch (IOException ioe) {
|
||||
throw new SSLException("readHandshakeRecord", ioe);
|
||||
}
|
||||
@ -1471,11 +1481,9 @@ public final class SSLSocketImpl
|
||||
buffer.position() > 0) {
|
||||
return buffer;
|
||||
}
|
||||
} catch (SSLException ssle) {
|
||||
throw ssle;
|
||||
} catch (InterruptedIOException iioe) {
|
||||
// don't change exception in case of timeouts or interrupts
|
||||
throw iioe;
|
||||
} catch (SSLException | InterruptedIOException | SocketException se) {
|
||||
// don't change exception in case of timeouts or interrupts or SocketException.
|
||||
throw se;
|
||||
} catch (IOException ioe) {
|
||||
if (!(ioe instanceof SSLException)) {
|
||||
throw new SSLException("readApplicationRecord", ioe);
|
||||
@ -1687,6 +1695,16 @@ public final class SSLSocketImpl
|
||||
}
|
||||
}
|
||||
|
||||
if (cause instanceof SocketException) {
|
||||
try {
|
||||
conContext.fatal(alert, cause);
|
||||
} catch (Exception e) {
|
||||
// Just delivering the fatal alert, re-throw the socket exception instead.
|
||||
}
|
||||
|
||||
throw (SocketException)cause;
|
||||
}
|
||||
|
||||
throw conContext.fatal(alert, cause);
|
||||
}
|
||||
|
||||
@ -1784,17 +1802,23 @@ public final class SSLSocketImpl
|
||||
SSLLogger.fine("wait for close_notify or alert");
|
||||
}
|
||||
|
||||
while (!conContext.isInboundClosed()) {
|
||||
try {
|
||||
Plaintext plainText = decode(null);
|
||||
// discard and continue
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.finest(
|
||||
"discard plaintext while waiting for close", plainText);
|
||||
appInput.readLock.lock();
|
||||
try {
|
||||
while (!conContext.isInboundClosed()) {
|
||||
try {
|
||||
Plaintext plainText = decode(null);
|
||||
// discard and continue
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
|
||||
SSLLogger.finest(
|
||||
"discard plaintext while waiting for close",
|
||||
plainText);
|
||||
}
|
||||
} catch (Exception e) { // including RuntimeException
|
||||
handleException(e);
|
||||
}
|
||||
} catch (Exception e) { // including RuntimeException
|
||||
handleException(e);
|
||||
}
|
||||
} finally {
|
||||
appInput.readLock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ final class SSLSocketOutputRecord extends OutputRecord implements SSLRecord {
|
||||
write(level);
|
||||
write(description);
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine("WRITE: " + protocolVersion +
|
||||
SSLLogger.fine("WRITE: " + protocolVersion.name +
|
||||
" " + ContentType.ALERT.name +
|
||||
"(" + Alert.nameOf(description) + ")" +
|
||||
", length = " + (count - headerSize));
|
||||
@ -180,7 +180,7 @@ final class SSLSocketOutputRecord extends OutputRecord implements SSLRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion +
|
||||
"WRITE: " + protocolVersion.name +
|
||||
" " + ContentType.HANDSHAKE.name +
|
||||
", length = " + (count - headerSize));
|
||||
}
|
||||
@ -256,7 +256,7 @@ final class SSLSocketOutputRecord extends OutputRecord implements SSLRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion +
|
||||
"WRITE: " + protocolVersion.name +
|
||||
" " + ContentType.HANDSHAKE.name +
|
||||
", length = " + (count - headerSize));
|
||||
}
|
||||
@ -329,7 +329,7 @@ final class SSLSocketOutputRecord extends OutputRecord implements SSLRecord {
|
||||
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("record")) {
|
||||
SSLLogger.fine(
|
||||
"WRITE: " + protocolVersion +
|
||||
"WRITE: " + protocolVersion.name +
|
||||
" " + ContentType.APPLICATION_DATA.name +
|
||||
", length = " + (count - position));
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, 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
|
||||
@ -28,6 +28,7 @@ package sun.security.ssl;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import javax.crypto.AEADBadTagException;
|
||||
import javax.crypto.BadPaddingException;
|
||||
@ -137,9 +138,9 @@ interface SSLTransport {
|
||||
} catch (EOFException eofe) {
|
||||
// rethrow EOFException, the call will handle it if neede.
|
||||
throw eofe;
|
||||
} catch (InterruptedIOException iioe) {
|
||||
// don't close the Socket in case of timeouts or interrupts.
|
||||
throw iioe;
|
||||
} catch (InterruptedIOException | SocketException se) {
|
||||
// don't close the Socket in case of timeouts or interrupts or SocketException.
|
||||
throw se;
|
||||
} catch (IOException ioe) {
|
||||
throw context.fatal(Alert.UNEXPECTED_MESSAGE, ioe);
|
||||
}
|
||||
|
||||
@ -560,9 +560,6 @@ final class ServerHello {
|
||||
|
||||
setUpPskKD(shc,
|
||||
shc.resumingSession.consumePreSharedKey());
|
||||
|
||||
// The session can't be resumed again---remove it from cache
|
||||
sessionCache.remove(shc.resumingSession.getSessionId());
|
||||
}
|
||||
|
||||
// update the responders
|
||||
|
||||
@ -100,6 +100,11 @@ public abstract class Cache<K,V> {
|
||||
*/
|
||||
public abstract void remove(Object key);
|
||||
|
||||
/**
|
||||
* Pull an entry from the cache.
|
||||
*/
|
||||
public abstract V pull(Object key);
|
||||
|
||||
/**
|
||||
* Set the maximum size.
|
||||
*/
|
||||
@ -224,6 +229,10 @@ class NullCache<K,V> extends Cache<K,V> {
|
||||
// empty
|
||||
}
|
||||
|
||||
public V pull(Object key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setCapacity(int size) {
|
||||
// empty
|
||||
}
|
||||
@ -402,6 +411,26 @@ class MemoryCache<K,V> extends Cache<K,V> {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized V pull(Object key) {
|
||||
emptyQueue();
|
||||
CacheEntry<K,V> entry = cacheMap.remove(key);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long time = (lifetime == 0) ? 0 : System.currentTimeMillis();
|
||||
if (entry.isValid(time)) {
|
||||
V value = entry.getValue();
|
||||
entry.invalidate();
|
||||
return value;
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println("Ignoring expired entry");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setCapacity(int size) {
|
||||
expungeExpiredEntries();
|
||||
if (size > 0 && cacheMap.size() > size) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -285,7 +285,7 @@ public class ZoneInfo extends TimeZone {
|
||||
int dstoffset = tz.getOffset(msec) - rawOffset;
|
||||
|
||||
// Check if it's in a standard-to-daylight transition.
|
||||
if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset) {
|
||||
if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset && type == WALL_TIME) {
|
||||
dstoffset = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -42,7 +42,7 @@ extern "C" {
|
||||
/*
|
||||
* AWTTrayIcon
|
||||
*/
|
||||
@interface AWTTrayIcon : NSObject {
|
||||
@interface AWTTrayIcon : NSObject <NSUserNotificationCenterDelegate>{
|
||||
jobject peer;
|
||||
AWTTrayIconView *view;
|
||||
NSStatusItem *theItem;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -69,11 +69,14 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize, BOOL autosize) {
|
||||
|
||||
view = [[AWTTrayIconView alloc] initWithTrayIcon:self];
|
||||
[theItem setView:view];
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc {
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
|
||||
|
||||
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
|
||||
JNFDeleteGlobalRef(env, peer);
|
||||
|
||||
@ -166,6 +169,12 @@ static NSSize ScaledImageSizeForStatusBar(NSSize imageSize, BOOL autosize) {
|
||||
(*env)->DeleteLocalRef(env, jEvent);
|
||||
}
|
||||
|
||||
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
|
||||
shouldPresentNotification:(NSUserNotification *)notification
|
||||
{
|
||||
return YES; // We always show notifications to the user
|
||||
}
|
||||
|
||||
@end //AWTTrayIcon
|
||||
//================================================
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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,7 +32,7 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <JavaNativeFoundation/JavaNativeFoundation.h>
|
||||
|
||||
JNIEXPORT @interface NSApplicationAWT : NSApplication <NSUserNotificationCenterDelegate> {
|
||||
JNIEXPORT @interface NSApplicationAWT : NSApplication {
|
||||
NSString *fApplicationName;
|
||||
NSWindow *eventTransparentWindow;
|
||||
NSTimeInterval dummyEventTimestamp;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -77,8 +77,6 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil];
|
||||
|
||||
[fApplicationName release];
|
||||
fApplicationName = nil;
|
||||
|
||||
@ -159,17 +157,10 @@ AWT_ASSERT_APPKIT_THREAD;
|
||||
|
||||
[super finishLaunching];
|
||||
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
|
||||
|
||||
// inform any interested parties that the AWT has arrived and is pumping
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:JNFRunLoopDidStartNotification object:self];
|
||||
}
|
||||
|
||||
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center
|
||||
shouldPresentNotification:(NSUserNotification *)notification
|
||||
{
|
||||
return YES; // We always show notifications to the user
|
||||
}
|
||||
|
||||
- (void) registerWithProcessManager
|
||||
{
|
||||
|
||||
@ -85,7 +85,7 @@ static jfieldID JPEGHuffmanTable_valuesID;
|
||||
/*
|
||||
* Defined in jpegdecoder.c. Copy code from there if and
|
||||
* when that disappears. */
|
||||
extern JavaVM *jvm;
|
||||
extern JavaVM *the_jvm;
|
||||
|
||||
/*
|
||||
* The following sets of defines must match the warning messages in the
|
||||
@ -557,7 +557,7 @@ sun_jpeg_output_message (j_common_ptr cinfo)
|
||||
char buffer[JMSG_LENGTH_MAX];
|
||||
jstring string;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
jobject theObject;
|
||||
|
||||
/* Create the message */
|
||||
@ -928,7 +928,7 @@ imageio_fill_input_buffer(j_decompress_ptr cinfo)
|
||||
struct jpeg_source_mgr *src = cinfo->src;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
streamBufferPtr sb = &data->streamBuf;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
int ret;
|
||||
jobject input = NULL;
|
||||
|
||||
@ -1021,7 +1021,7 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo)
|
||||
struct jpeg_source_mgr *src = cinfo->src;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
streamBufferPtr sb = &data->streamBuf;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
jint ret;
|
||||
size_t offset, buflen;
|
||||
jobject input = NULL;
|
||||
@ -1122,7 +1122,7 @@ imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
||||
struct jpeg_source_mgr *src = cinfo->src;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
streamBufferPtr sb = &data->streamBuf;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
jlong ret;
|
||||
jobject reader;
|
||||
jobject input = NULL;
|
||||
@ -1207,7 +1207,7 @@ imageio_term_source(j_decompress_ptr cinfo)
|
||||
// To pushback, just seek back by src->bytes_in_buffer
|
||||
struct jpeg_source_mgr *src = cinfo->src;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
jobject reader = data->imageIOobj;
|
||||
if (src->bytes_in_buffer > 0) {
|
||||
RELEASE_ARRAYS(env, data, src->next_input_byte);
|
||||
@ -2369,7 +2369,7 @@ imageio_init_destination (j_compress_ptr cinfo)
|
||||
struct jpeg_destination_mgr *dest = cinfo->dest;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
streamBufferPtr sb = &data->streamBuf;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
|
||||
if (sb->buf == NULL) {
|
||||
// We forgot to pin the array
|
||||
@ -2395,7 +2395,7 @@ imageio_empty_output_buffer (j_compress_ptr cinfo)
|
||||
struct jpeg_destination_mgr *dest = cinfo->dest;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
streamBufferPtr sb = &data->streamBuf;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
jobject output = NULL;
|
||||
|
||||
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
|
||||
@ -2431,7 +2431,7 @@ imageio_term_destination (j_compress_ptr cinfo)
|
||||
struct jpeg_destination_mgr *dest = cinfo->dest;
|
||||
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
|
||||
streamBufferPtr sb = &data->streamBuf;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
|
||||
/* find out how much needs to be written */
|
||||
/* this conversion from size_t to jint is safe, because the lenght of the buffer is limited by jint */
|
||||
|
||||
@ -64,12 +64,12 @@ static jmethodID InputStream_availableID;
|
||||
|
||||
/* Initialize the Java VM instance variable when the library is
|
||||
first loaded */
|
||||
JavaVM *jvm;
|
||||
JavaVM *the_jvm;
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
jvm = vm;
|
||||
the_jvm = vm;
|
||||
return JNI_VERSION_1_2;
|
||||
}
|
||||
|
||||
@ -284,7 +284,7 @@ GLOBAL(boolean)
|
||||
sun_jpeg_fill_input_buffer(j_decompress_ptr cinfo)
|
||||
{
|
||||
sun_jpeg_source_ptr src = (sun_jpeg_source_ptr) cinfo->src;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
int ret, buflen;
|
||||
|
||||
if (src->suspendable) {
|
||||
@ -327,7 +327,7 @@ GLOBAL(void)
|
||||
sun_jpeg_fill_suspended_buffer(j_decompress_ptr cinfo)
|
||||
{
|
||||
sun_jpeg_source_ptr src = (sun_jpeg_source_ptr) cinfo->src;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
size_t offset, buflen;
|
||||
int ret;
|
||||
|
||||
@ -397,7 +397,7 @@ GLOBAL(void)
|
||||
sun_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
sun_jpeg_source_ptr src = (sun_jpeg_source_ptr) cinfo->src;
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(the_jvm, JNI_VERSION_1_2);
|
||||
int ret;
|
||||
int buflen;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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,6 @@
|
||||
package sun.print;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.print.DocFlavor;
|
||||
import javax.print.MultiDocPrintService;
|
||||
@ -50,31 +48,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup {
|
||||
private String[] printers; /* excludes the default printer */
|
||||
private PrintService[] printServices; /* includes the default printer */
|
||||
|
||||
private static final int DEFAULT_REFRESH_TIME = 240; // 4 minutes
|
||||
private static final int MINIMUM_REFRESH_TIME = 120; // 2 minutes
|
||||
private static final boolean pollServices;
|
||||
private static final int refreshTime;
|
||||
|
||||
static {
|
||||
/* The system property "sun.java2d.print.polling"
|
||||
* can be used to force the printing code to poll or not poll
|
||||
* for PrintServices.
|
||||
*/
|
||||
String pollStr = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));
|
||||
pollServices = !("false".equalsIgnoreCase(pollStr));
|
||||
|
||||
/* The system property "sun.java2d.print.minRefreshTime"
|
||||
* can be used to specify minimum refresh time (in seconds)
|
||||
* for polling PrintServices. The default is 240.
|
||||
*/
|
||||
String refreshTimeStr = java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction(
|
||||
"sun.java2d.print.minRefreshTime"));
|
||||
refreshTime = (refreshTimeStr != null)
|
||||
? getRefreshTime(refreshTimeStr)
|
||||
: DEFAULT_REFRESH_TIME;
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
@ -84,17 +58,6 @@ public class PrintServiceLookupProvider extends PrintServiceLookup {
|
||||
});
|
||||
}
|
||||
|
||||
private static int getRefreshTime(final String refreshTimeStr) {
|
||||
try {
|
||||
int minRefreshTime = Integer.parseInt(refreshTimeStr);
|
||||
return (minRefreshTime < MINIMUM_REFRESH_TIME)
|
||||
? MINIMUM_REFRESH_TIME
|
||||
: minRefreshTime;
|
||||
} catch (NumberFormatException e) {
|
||||
return DEFAULT_REFRESH_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
/* The singleton win32 print lookup service.
|
||||
* Code that is aware of this field and wants to use it must first
|
||||
* see if its null, and if so instantiate it by calling a method such as
|
||||
@ -126,13 +89,11 @@ public class PrintServiceLookupProvider extends PrintServiceLookup {
|
||||
thr.setDaemon(true);
|
||||
thr.start();
|
||||
|
||||
if (pollServices) {
|
||||
// start the remote printer listener thread
|
||||
Thread remThr = new Thread(null, new RemotePrinterChangeListener(),
|
||||
"RemotePrinterListener", 0, false);
|
||||
remThr.setDaemon(true);
|
||||
remThr.start();
|
||||
}
|
||||
// start the remote printer listener thread
|
||||
Thread remThr = new Thread(null, new RemotePrinterChangeListener(),
|
||||
"RemotePrinterListener", 0, false);
|
||||
remThr.setDaemon(true);
|
||||
remThr.start();
|
||||
} /* else condition ought to never happen! */
|
||||
}
|
||||
|
||||
@ -356,70 +317,15 @@ public class PrintServiceLookupProvider extends PrintServiceLookup {
|
||||
}
|
||||
}
|
||||
|
||||
/* Windows provides *PrinterChangeNotification* functions that provides
|
||||
information about printer status changes of the local printers but not
|
||||
network printers.
|
||||
Alternatively, Windows provides a way through which one can get the
|
||||
network printer status changes by using WMI, RegistryKeyChange combination,
|
||||
which is a slightly complex mechanism.
|
||||
The Windows WMI offers an async and sync method to read through registry
|
||||
via the WQL query. The async method is considered dangerous as it leaves
|
||||
open a channel until we close it. But the async method has the advantage of
|
||||
being notified of a change in registry by calling callback without polling for it.
|
||||
The sync method uses the polling mechanism to notify.
|
||||
RegistryValueChange cannot be used in combination with WMI to get registry
|
||||
value change notification because of an error that may be generated because the
|
||||
scope of the query would be too big to handle(at times).
|
||||
Hence an alternative mechanism is chosen via the EnumPrinters by polling for the
|
||||
count of printer status changes(add\remove) and based on it update the printers
|
||||
list.
|
||||
*/
|
||||
class RemotePrinterChangeListener implements Comparator<String>, Runnable {
|
||||
|
||||
RemotePrinterChangeListener() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
return ((o1 == null)
|
||||
? ((o2 == null) ? 0 : 1)
|
||||
: ((o2 == null) ? -1 : o1.compareTo(o2)));
|
||||
}
|
||||
|
||||
private final class RemotePrinterChangeListener implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
// Init the list of remote printers
|
||||
String[] prevRemotePrinters = getRemotePrintersNames();
|
||||
if (prevRemotePrinters != null) {
|
||||
Arrays.sort(prevRemotePrinters, this);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(refreshTime * 1000);
|
||||
} catch (InterruptedException e) {
|
||||
break;
|
||||
}
|
||||
|
||||
String[] currentRemotePrinters = getRemotePrintersNames();
|
||||
if (currentRemotePrinters != null) {
|
||||
Arrays.sort(currentRemotePrinters, this);
|
||||
}
|
||||
if (!Arrays.equals(prevRemotePrinters, currentRemotePrinters)) {
|
||||
// The list of remote printers got updated,
|
||||
// so update the cached list printers which
|
||||
// includes both local and network printers
|
||||
refreshServices();
|
||||
|
||||
// store the current data for next comparison
|
||||
prevRemotePrinters = currentRemotePrinters;
|
||||
}
|
||||
}
|
||||
notifyRemotePrinterChange(); // busy loop in the native code
|
||||
}
|
||||
}
|
||||
|
||||
private native String getDefaultPrinterName();
|
||||
private native String[] getAllPrinterNames();
|
||||
private native void notifyLocalPrinterChange();
|
||||
private native String[] getRemotePrintersNames();
|
||||
private native void notifyRemotePrinterChange();
|
||||
}
|
||||
|
||||
@ -191,12 +191,6 @@ Java_sun_print_PrintServiceLookupProvider_getAllPrinterNames(JNIEnv *env,
|
||||
return getPrinterNames(env, PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS);
|
||||
}
|
||||
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
Java_sun_print_PrintServiceLookupProvider_getRemotePrintersNames(JNIEnv *env,
|
||||
jobject peer)
|
||||
{
|
||||
return getPrinterNames(env, PRINTER_ENUM_CONNECTIONS);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_print_PrintServiceLookupProvider_notifyLocalPrinterChange(JNIEnv *env,
|
||||
@ -239,6 +233,37 @@ Java_sun_print_PrintServiceLookupProvider_notifyLocalPrinterChange(JNIEnv *env,
|
||||
::ClosePrinter(hPrinter);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_sun_print_PrintServiceLookupProvider_notifyRemotePrinterChange(JNIEnv *env,
|
||||
jobject peer)
|
||||
{
|
||||
jclass cls = env->GetObjectClass(peer);
|
||||
CHECK_NULL(cls);
|
||||
jmethodID refresh = env->GetMethodID(cls, "refreshServices", "()V");
|
||||
CHECK_NULL(refresh);
|
||||
|
||||
HKEY hKey;
|
||||
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER,
|
||||
_T("Printers\\Connections"),
|
||||
0, KEY_NOTIFY, &hKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL keepMonitoring;
|
||||
do {
|
||||
keepMonitoring =
|
||||
ERROR_SUCCESS == RegNotifyChangeKeyValue(hKey, TRUE,
|
||||
REG_NOTIFY_CHANGE_NAME,
|
||||
NULL,
|
||||
FALSE);
|
||||
if (keepMonitoring) {
|
||||
env->CallVoidMethod(peer, refresh);
|
||||
}
|
||||
} while (keepMonitoring && !env->ExceptionCheck());
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jfloatArray JNICALL
|
||||
Java_sun_print_Win32PrintService_getMediaPrintableArea(JNIEnv *env,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 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
|
||||
@ -432,7 +432,7 @@ class WindowsPreferences extends AbstractPreferences {
|
||||
if (result[ERROR_CODE] != ERROR_SUCCESS) {
|
||||
logger().warning("Could not create windows registry node " +
|
||||
byteArrayToString(windowsAbsolutePath()) +
|
||||
" at root 0x" + Long.toHexString(rootNativeHandle()) +
|
||||
" at root 0x" + Long.toHexString(parentNativeHandle) +
|
||||
". Windows RegCreateKeyEx(...) returned error code " +
|
||||
result[ERROR_CODE] + ".");
|
||||
isBackingStoreAvailable = false;
|
||||
@ -458,7 +458,7 @@ class WindowsPreferences extends AbstractPreferences {
|
||||
if (result[ERROR_CODE] != ERROR_SUCCESS) {
|
||||
logger().warning("Could not open/create prefs root node " +
|
||||
byteArrayToString(windowsAbsolutePath()) +
|
||||
" at root 0x" + Long.toHexString(rootNativeHandle()) +
|
||||
" at root 0x" + Long.toHexString(rootNativeHandle) +
|
||||
". Windows RegCreateKeyEx(...) returned error code " +
|
||||
result[ERROR_CODE] + ".");
|
||||
isBackingStoreAvailable = false;
|
||||
|
||||
@ -70,7 +70,7 @@ final class P11Cipher extends CipherSpi {
|
||||
private static interface Padding {
|
||||
// ENC: format the specified buffer with padding bytes and return the
|
||||
// actual padding length
|
||||
int setPaddingBytes(byte[] paddingBuffer, int padLen);
|
||||
int setPaddingBytes(byte[] paddingBuffer, int startOff, int padLen);
|
||||
|
||||
// DEC: return the length of trailing padding bytes given the specified
|
||||
// padded data
|
||||
@ -91,8 +91,8 @@ final class P11Cipher extends CipherSpi {
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
|
||||
public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
|
||||
Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
|
||||
public int setPaddingBytes(byte[] paddingBuffer, int startOff, int padLen) {
|
||||
Arrays.fill(paddingBuffer, startOff, startOff + padLen, (byte) (padLen & 0x007f));
|
||||
return padLen;
|
||||
}
|
||||
|
||||
@ -169,6 +169,14 @@ final class P11Cipher extends CipherSpi {
|
||||
// specification mandates a fixed size of the key
|
||||
private int fixedKeySize = -1;
|
||||
|
||||
// Indicates whether the underlying PKCS#11 library requires block-sized
|
||||
// updates during multi-part operations. In such case, we buffer data in
|
||||
// padBuffer up to a block-size. This may be needed only if padding is
|
||||
// applied on the Java side. An example of the previous is when the
|
||||
// CKM_AES_ECB mechanism is used and the PKCS#11 library is NSS. See more
|
||||
// on JDK-8261355.
|
||||
private boolean reqBlockUpdates = false;
|
||||
|
||||
P11Cipher(Token token, String algorithm, long mechanism)
|
||||
throws PKCS11Exception, NoSuchAlgorithmException {
|
||||
super();
|
||||
@ -252,6 +260,10 @@ final class P11Cipher extends CipherSpi {
|
||||
// no native padding support; use our own padding impl
|
||||
paddingObj = new PKCS5Padding(blockSize);
|
||||
padBuffer = new byte[blockSize];
|
||||
char[] tokenLabel = token.tokenInfo.label;
|
||||
// NSS requires block-sized updates in multi-part operations.
|
||||
reqBlockUpdates = ((tokenLabel[0] == 'N' && tokenLabel[1] == 'S'
|
||||
&& tokenLabel[2] == 'S') ? true : false);
|
||||
}
|
||||
} else {
|
||||
throw new NoSuchPaddingException("Unsupported padding " + padding);
|
||||
@ -580,46 +592,54 @@ final class P11Cipher extends CipherSpi {
|
||||
try {
|
||||
ensureInitialized();
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
|
||||
0, out, outOfs, outLen);
|
||||
} else {
|
||||
int newPadBufferLen = 0;
|
||||
if (paddingObj != null) {
|
||||
if (padBufferLen != 0) {
|
||||
// NSS throws up when called with data not in multiple
|
||||
// of blocks. Try to work around this by holding the
|
||||
// extra data in padBuffer.
|
||||
if (padBufferLen != padBuffer.length) {
|
||||
int bufCapacity = padBuffer.length - padBufferLen;
|
||||
if (inLen > bufCapacity) {
|
||||
bufferInputBytes(in, inOfs, bufCapacity);
|
||||
inOfs += bufCapacity;
|
||||
inLen -= bufCapacity;
|
||||
} else {
|
||||
bufferInputBytes(in, inOfs, inLen);
|
||||
return 0;
|
||||
}
|
||||
int newPadBufferLen = 0;
|
||||
if (paddingObj != null && (!encrypt || reqBlockUpdates)) {
|
||||
if (padBufferLen != 0) {
|
||||
if (padBufferLen != padBuffer.length) {
|
||||
int bufCapacity = padBuffer.length - padBufferLen;
|
||||
if (inLen > bufCapacity) {
|
||||
bufferInputBytes(in, inOfs, bufCapacity);
|
||||
inOfs += bufCapacity;
|
||||
inLen -= bufCapacity;
|
||||
} else {
|
||||
bufferInputBytes(in, inOfs, inLen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (encrypt) {
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
0, padBuffer, 0, padBufferLen,
|
||||
0, out, outOfs, outLen);
|
||||
} else {
|
||||
k = token.p11.C_DecryptUpdate(session.id(),
|
||||
0, padBuffer, 0, padBufferLen,
|
||||
0, out, outOfs, outLen);
|
||||
padBufferLen = 0;
|
||||
}
|
||||
newPadBufferLen = inLen & (blockSize - 1);
|
||||
if (newPadBufferLen == 0) {
|
||||
newPadBufferLen = padBuffer.length;
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
padBufferLen = 0;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
newPadBufferLen = inLen & (blockSize - 1);
|
||||
if (!encrypt && newPadBufferLen == 0) {
|
||||
// While decrypting with implUpdate, the last encrypted block
|
||||
// is always held in a buffer. If it's the final one (unknown
|
||||
// at this point), it may contain padding bytes and need further
|
||||
// processing. In implDoFinal (where we know it's the final one)
|
||||
// the buffer is decrypted, unpadded and returned.
|
||||
newPadBufferLen = padBuffer.length;
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
if (encrypt) {
|
||||
k += token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs,
|
||||
inLen, 0, out, (outOfs + k), (outLen - k));
|
||||
} else {
|
||||
k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
|
||||
inLen, 0, out, (outOfs + k), (outLen - k));
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null) {
|
||||
bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
|
||||
}
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null && newPadBufferLen > 0) {
|
||||
bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
|
||||
}
|
||||
bytesBuffered += (inLen - k);
|
||||
return k;
|
||||
@ -676,60 +696,62 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
int newPadBufferLen = 0;
|
||||
if (paddingObj != null && (!encrypt || reqBlockUpdates)) {
|
||||
if (padBufferLen != 0) {
|
||||
if (padBufferLen != padBuffer.length) {
|
||||
int bufCapacity = padBuffer.length - padBufferLen;
|
||||
if (inLen > bufCapacity) {
|
||||
bufferInputBytes(inBuffer, bufCapacity);
|
||||
inOfs += bufCapacity;
|
||||
inLen -= bufCapacity;
|
||||
} else {
|
||||
bufferInputBytes(inBuffer, inLen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (encrypt) {
|
||||
k = token.p11.C_EncryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||
outOfs, outLen);
|
||||
} else {
|
||||
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||
outOfs, outLen);
|
||||
}
|
||||
padBufferLen = 0;
|
||||
}
|
||||
newPadBufferLen = inLen & (blockSize - 1);
|
||||
if (!encrypt && newPadBufferLen == 0) {
|
||||
// While decrypting with implUpdate, the last encrypted block
|
||||
// is always held in a buffer. If it's the final one (unknown
|
||||
// at this point), it may contain padding bytes and need further
|
||||
// processing. In implDoFinal (where we know it's the final one)
|
||||
// the buffer is decrypted, unpadded and returned.
|
||||
newPadBufferLen = padBuffer.length;
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
if (inAddr == 0 && inArray == null) {
|
||||
inArray = new byte[inLen];
|
||||
inBuffer.get(inArray);
|
||||
} else {
|
||||
inBuffer.position(origPos + inLen);
|
||||
inBuffer.position(inBuffer.position() + inLen);
|
||||
}
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
inAddr, inArray, inOfs, inLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
} else {
|
||||
int newPadBufferLen = 0;
|
||||
if (paddingObj != null) {
|
||||
if (padBufferLen != 0) {
|
||||
// NSS throws up when called with data not in multiple
|
||||
// of blocks. Try to work around this by holding the
|
||||
// extra data in padBuffer.
|
||||
if (padBufferLen != padBuffer.length) {
|
||||
int bufCapacity = padBuffer.length - padBufferLen;
|
||||
if (inLen > bufCapacity) {
|
||||
bufferInputBytes(inBuffer, bufCapacity);
|
||||
inOfs += bufCapacity;
|
||||
inLen -= bufCapacity;
|
||||
} else {
|
||||
bufferInputBytes(inBuffer, inLen);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
k = token.p11.C_DecryptUpdate(session.id(), 0,
|
||||
padBuffer, 0, padBufferLen, outAddr, outArray,
|
||||
outOfs, outLen);
|
||||
padBufferLen = 0;
|
||||
}
|
||||
newPadBufferLen = inLen & (blockSize - 1);
|
||||
if (newPadBufferLen == 0) {
|
||||
newPadBufferLen = padBuffer.length;
|
||||
}
|
||||
inLen -= newPadBufferLen;
|
||||
}
|
||||
if (inLen > 0) {
|
||||
if (inAddr == 0 && inArray == null) {
|
||||
inArray = new byte[inLen];
|
||||
inBuffer.get(inArray);
|
||||
} else {
|
||||
inBuffer.position(inBuffer.position() + inLen);
|
||||
}
|
||||
if (encrypt) {
|
||||
k += token.p11.C_EncryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - k));
|
||||
} else {
|
||||
k += token.p11.C_DecryptUpdate(session.id(), inAddr,
|
||||
inArray, inOfs, inLen, outAddr, outArray,
|
||||
(outOfs + k), (outLen - k));
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null && newPadBufferLen != 0) {
|
||||
bufferInputBytes(inBuffer, newPadBufferLen);
|
||||
}
|
||||
}
|
||||
// update 'padBuffer' if using our own padding impl.
|
||||
if (paddingObj != null && newPadBufferLen > 0) {
|
||||
bufferInputBytes(inBuffer, newPadBufferLen);
|
||||
}
|
||||
bytesBuffered += (inLen - k);
|
||||
if (!(outBuffer instanceof DirectBuffer) &&
|
||||
@ -764,10 +786,14 @@ final class P11Cipher extends CipherSpi {
|
||||
int k = 0;
|
||||
if (encrypt) {
|
||||
if (paddingObj != null) {
|
||||
int startOff = 0;
|
||||
if (reqBlockUpdates) {
|
||||
startOff = padBufferLen;
|
||||
}
|
||||
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
|
||||
requiredOutLen - bytesBuffered);
|
||||
startOff, requiredOutLen - bytesBuffered);
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
0, padBuffer, 0, actualPadLen,
|
||||
0, padBuffer, 0, startOff + actualPadLen,
|
||||
0, out, outOfs, outLen);
|
||||
}
|
||||
k += token.p11.C_EncryptFinal(session.id(),
|
||||
@ -839,10 +865,14 @@ final class P11Cipher extends CipherSpi {
|
||||
|
||||
if (encrypt) {
|
||||
if (paddingObj != null) {
|
||||
int startOff = 0;
|
||||
if (reqBlockUpdates) {
|
||||
startOff = padBufferLen;
|
||||
}
|
||||
int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
|
||||
requiredOutLen - bytesBuffered);
|
||||
startOff, requiredOutLen - bytesBuffered);
|
||||
k = token.p11.C_EncryptUpdate(session.id(),
|
||||
0, padBuffer, 0, actualPadLen,
|
||||
0, padBuffer, 0, startOff + actualPadLen,
|
||||
outAddr, outArray, outOfs, outLen);
|
||||
}
|
||||
k += token.p11.C_EncryptFinal(session.id(),
|
||||
|
||||
@ -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.interfaces.*;
|
||||
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 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||
rsaKey.getModulus(),
|
||||
rsaKey.getPublicExponent()
|
||||
);
|
||||
} else if ("X.509".equals(key.getFormat())) {
|
||||
// let SunRsaSign provider parse for us, then recurse
|
||||
byte[] encoded = key.getEncoded();
|
||||
key = RSAPublicKeyImpl.newKey(encoded);
|
||||
return implTranslatePublicKey(key);
|
||||
} else {
|
||||
throw new InvalidKeyException("PublicKey must be instance "
|
||||
+ "of RSAPublicKey or have X.509 encoding");
|
||||
// let SunRsaSign provider parse for us, then recurse
|
||||
key = RSAPublicKeyImpl.newKey(KeyType.RSA, key.getFormat(),
|
||||
key.getEncoded());
|
||||
return implTranslatePublicKey(key);
|
||||
}
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeyException("Could not create RSA public key", e);
|
||||
@ -93,14 +92,11 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||
rsaKey.getModulus(),
|
||||
rsaKey.getPrivateExponent()
|
||||
);
|
||||
} else if ("PKCS#8".equals(key.getFormat())) {
|
||||
// let SunRsaSign provider parse for us, then recurse
|
||||
byte[] encoded = key.getEncoded();
|
||||
key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
|
||||
return implTranslatePrivateKey(key);
|
||||
} else {
|
||||
throw new InvalidKeyException("Private key must be instance "
|
||||
+ "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
|
||||
// let SunRsaSign provider parse for us, then recurse
|
||||
key = RSAPrivateCrtKeyImpl.newKey(KeyType.RSA, key.getFormat(),
|
||||
key.getEncoded());
|
||||
return implTranslatePrivateKey(key);
|
||||
}
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new InvalidKeyException("Could not create RSA private key", e);
|
||||
@ -113,8 +109,8 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||
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 @@ final class P11RSAKeyFactory extends P11KeyFactory {
|
||||
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
|
||||
|
||||
@ -576,17 +576,42 @@ class ServerImpl implements TimeSource {
|
||||
start = space+1;
|
||||
String version = requestLine.substring (start);
|
||||
Headers headers = req.headers();
|
||||
String s = headers.getFirst ("Transfer-encoding");
|
||||
/* check key for illegal characters */
|
||||
for (var k : headers.keySet()) {
|
||||
if (!isValidHeaderKey(k)) {
|
||||
reject(Code.HTTP_BAD_REQUEST, requestLine,
|
||||
"Header key contains illegal characters");
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* checks for unsupported combinations of lengths and encodings */
|
||||
if (headers.containsKey("Content-Length") &&
|
||||
(headers.containsKey("Transfer-encoding") || headers.get("Content-Length").size() > 1)) {
|
||||
reject(Code.HTTP_BAD_REQUEST, requestLine,
|
||||
"Conflicting or malformed headers detected");
|
||||
return;
|
||||
}
|
||||
long clen = 0L;
|
||||
if (s !=null && s.equalsIgnoreCase ("chunked")) {
|
||||
clen = -1L;
|
||||
String headerValue = null;
|
||||
List<String> teValueList = headers.get("Transfer-encoding");
|
||||
if (teValueList != null && !teValueList.isEmpty()) {
|
||||
headerValue = teValueList.get(0);
|
||||
}
|
||||
if (headerValue != null) {
|
||||
if (headerValue.equalsIgnoreCase("chunked") && teValueList.size() == 1) {
|
||||
clen = -1L;
|
||||
} else {
|
||||
reject(Code.HTTP_NOT_IMPLEMENTED,
|
||||
requestLine, "Unsupported Transfer-Encoding value");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
s = headers.getFirst ("Content-Length");
|
||||
if (s != null) {
|
||||
clen = Long.parseLong(s);
|
||||
headerValue = headers.getFirst("Content-Length");
|
||||
if (headerValue != null) {
|
||||
clen = Long.parseLong(headerValue);
|
||||
}
|
||||
if (clen == 0) {
|
||||
requestCompleted (connection);
|
||||
requestCompleted(connection);
|
||||
}
|
||||
}
|
||||
ctx = contexts.findContext (protocol, uri.getPath());
|
||||
@ -896,4 +921,24 @@ class ServerImpl implements TimeSource {
|
||||
return secs * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates a RFC 7230 header-key.
|
||||
*/
|
||||
static boolean isValidHeaderKey(String token) {
|
||||
if (token == null) return false;
|
||||
|
||||
boolean isValidChar;
|
||||
char[] chars = token.toCharArray();
|
||||
String validSpecialChars = "!#$%&'*+-.^_`|~";
|
||||
for (char c : chars) {
|
||||
isValidChar = ((c >= 'a') && (c <= 'z')) ||
|
||||
((c >= 'A') && (c <= 'Z')) ||
|
||||
((c >= '0') && (c <= '9'));
|
||||
if (!isValidChar && validSpecialChars.indexOf(c) == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !token.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ public class Extern {
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
Fault(String msg, Exception cause) {
|
||||
super(msg, cause);
|
||||
super(msg + (cause == null ? "" : " (" + cause + ")"), cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.2</version>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2021 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires vm.gc.Serial
|
||||
* @bug 8262295
|
||||
* @library /test/lib /
|
||||
* @summary Out of bounds array load on clone source crashes GC which
|
||||
* interpretes the loaded value as oop. A small heap is configured to
|
||||
* get a lot of GCs.
|
||||
*
|
||||
* @comment C2 generates the out of bounds load with serial, parallel and
|
||||
* shenandoah gc but not with g1 and z gc. For simplicity serial gc is
|
||||
* configured.
|
||||
*
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* @run main/othervm -XX:+UseSerialGC -Xmx128m
|
||||
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||
* -XX:-BackgroundCompilation
|
||||
* -XX:CompileCommand=dontinline,*::*_dontinline
|
||||
* compiler.arraycopy.TestOutOfBoundsArrayLoad
|
||||
*/
|
||||
|
||||
package compiler.arraycopy;
|
||||
|
||||
import compiler.whitebox.CompilerWhiteBoxTest;
|
||||
|
||||
public class TestOutOfBoundsArrayLoad {
|
||||
|
||||
public static Object escape1;
|
||||
public static Object escape2;
|
||||
|
||||
public static void main(String[] args_ignored) {
|
||||
try {
|
||||
Object[] arrNotEmpty = {null, null, null, null, null, };
|
||||
|
||||
// Warm-up
|
||||
for (int i = CompilerWhiteBoxTest.THRESHOLD; i > 0; i--) {
|
||||
testMethod_dontinline(arrNotEmpty);
|
||||
}
|
||||
// Call testmethod with empty array often enough to trigger GC.
|
||||
// GC is assumed to crash.
|
||||
for (int i = 20_000_000; i > 0; i--) {
|
||||
// Trick for ParallelGC: empty[4] will be loaded in the testmethod
|
||||
// (out of bounds!) and interpreted as oop (or
|
||||
// narrowOop). PSScavenge::should_scavenge() will skip the loaded
|
||||
// value if it is before the young generation. So before calling the
|
||||
// test method we allocate the empty array and an array of -1 values
|
||||
// right behind it. So empty[4] will likely result in
|
||||
// 0xffffffffffffffff Which is not before the young generation.
|
||||
Object[] empty = new Object[0];
|
||||
long[] l = new long[4];
|
||||
l[0] = -1L; l[1] = -1L; l[2] = -1L; l[3] = -1L;
|
||||
escape2 = l;
|
||||
testMethod_dontinline(empty);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testMethod_dontinline(Object[] src) throws Exception {
|
||||
Object[] clone = src.clone();
|
||||
// Load L below is executed speculatively at this point from src without range check.
|
||||
// The result is put into the OopMap of the allocation in the next line.
|
||||
// If src.length is 0 then the loaded value is no heap reference and GC crashes.
|
||||
escape1 = new Object();
|
||||
if (src.length > 4) {
|
||||
escape2 = clone[4]; // Load L
|
||||
}
|
||||
}
|
||||
}
|
||||
69
test/hotspot/jtreg/gc/shenandoah/options/TestLargePages.java
Normal file
69
test/hotspot/jtreg/gc/shenandoah/options/TestLargePages.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 id=default
|
||||
* @requires vm.gc.Shenandoah
|
||||
*
|
||||
* @run main/othervm -XX:+UseShenandoahGC -Xms128m -Xmx128m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -Xmx128m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -Xms128m TestLargePages
|
||||
*
|
||||
* @run main/othervm -XX:+UseShenandoahGC -Xms131m -Xmx131m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -Xmx131m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -Xms131m TestLargePages
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test id=lp
|
||||
* @requires vm.gc.Shenandoah
|
||||
*
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseLargePages -Xms128m -Xmx128m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseLargePages -Xmx128m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseLargePages -Xms128m TestLargePages
|
||||
*
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseLargePages -Xms131m -Xmx131m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseLargePages -Xmx131m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseLargePages -Xms131m TestLargePages
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test id=thp
|
||||
* @requires vm.gc.Shenandoah
|
||||
* @requires os.family == "linux"
|
||||
*
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseTransparentHugePages -Xms128m -Xmx128m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseTransparentHugePages -Xmx128m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseTransparentHugePages -Xms128m TestLargePages
|
||||
*
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseTransparentHugePages -Xms131m -Xmx131m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseTransparentHugePages -Xmx131m TestLargePages
|
||||
* @run main/othervm -XX:+UseShenandoahGC -XX:+UseTransparentHugePages -Xms131m TestLargePages
|
||||
*/
|
||||
|
||||
public class TestLargePages {
|
||||
public static void main(String[] args) {
|
||||
// Everything is checked on initialization
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2019, 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
|
||||
@ -23,10 +23,10 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8153732 8212202 8221263 8221412 8222108
|
||||
* @bug 8153732 8212202 8221263 8221412 8222108 8263311
|
||||
* @requires (os.family == "Windows")
|
||||
* @summary Windows remote printer changes do not reflect in lookupPrintServices()
|
||||
* @run main/manual/othervm -Dsun.java2d.print.minRefreshTime=120 RemotePrinterStatusRefresh
|
||||
* @run main/manual RemotePrinterStatusRefresh
|
||||
*/
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
@ -63,12 +63,7 @@ import static javax.swing.BorderFactory.createTitledBorder;
|
||||
|
||||
public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
|
||||
private static final long DEFAULT_REFRESH_TIME = 240L;
|
||||
private static final long MINIMAL_REFRESH_TIME = 120L;
|
||||
|
||||
private static final long refreshTime = getRefreshTime();
|
||||
|
||||
private static final long TIMEOUT = refreshTime * 4 + 60;
|
||||
private static final long TIMEOUT = 15L * 60;
|
||||
|
||||
|
||||
private static final CountDownLatch latch = new CountDownLatch(1);
|
||||
@ -86,7 +81,6 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
private final ServiceItemListModel beforeList;
|
||||
private final ServiceItemListModel afterList;
|
||||
|
||||
private JTextField nextRefresh;
|
||||
private JTextField timeLeft;
|
||||
|
||||
private final Timer timer;
|
||||
@ -184,22 +178,18 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
+ "configured printers.\n"
|
||||
+ "Step 1: Add or Remove a network printer using "
|
||||
+ "Windows Control Panel.\n"
|
||||
+ "Step 2: Wait for 2\u20134 minutes after adding or removing.\n"
|
||||
+ " \"Next printer refresh in\" gives you a "
|
||||
+ "rough estimation on when update will happen.\n"
|
||||
+ "Step 3: Click Refresh."
|
||||
+ "Step 2: Click Refresh."
|
||||
+ "\"After\" list is populated with updated list "
|
||||
+ "of printers.\n"
|
||||
+ "Step 4: Compare the list of printers in \"Before\" and "
|
||||
+ "Step 3: Compare the list of printers in \"Before\" and "
|
||||
+ "\"After\" lists.\n"
|
||||
+ " Added printers are highlighted with "
|
||||
+ "green color, removed ones \u2014 with "
|
||||
+ "red color.\n"
|
||||
+ "Step 5: Click Pass if the list of printers is correctly "
|
||||
+ "Step 4: Click Pass if the list of printers is correctly "
|
||||
+ "updated.\n"
|
||||
+ "Step 6: If the list is not updated, wait for another "
|
||||
+ "2\u20134 minutes, and then click Refresh again.\n"
|
||||
+ "Step 7: If the list does not update, click Fail.\n"
|
||||
+ "Step 5: If the list is not updated, click Refresh again.\n"
|
||||
+ "Step 6: If the list does not update, click Fail.\n"
|
||||
+ "\n"
|
||||
+ "You have to click Refresh to enable Pass and Fail buttons. "
|
||||
+ "If no button is pressed,\n"
|
||||
@ -216,18 +206,6 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
private static long getRefreshTime() {
|
||||
String refreshTime =
|
||||
System.getProperty("sun.java2d.print.minRefreshTime",
|
||||
Long.toString(DEFAULT_REFRESH_TIME));
|
||||
try {
|
||||
long value = Long.parseLong(refreshTime);
|
||||
return value < MINIMAL_REFRESH_TIME ? MINIMAL_REFRESH_TIME : value;
|
||||
} catch (NumberFormatException e) {
|
||||
return DEFAULT_REFRESH_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
private static void createUI() {
|
||||
test = new RemotePrinterStatusRefresh();
|
||||
}
|
||||
@ -278,31 +256,6 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
javaVersion.setEditable(false);
|
||||
javaLabel.setLabelFor(javaVersion);
|
||||
|
||||
JLabel refreshTimeLabel = new JLabel("Refresh interval:");
|
||||
long minutes = refreshTime / 60;
|
||||
long seconds = refreshTime % 60;
|
||||
String interval = String.format("%1$d seconds%2$s",
|
||||
refreshTime,
|
||||
minutes > 0
|
||||
? String.format(" (%1$d %2$s%3$s)",
|
||||
minutes,
|
||||
minutes > 1 ? "minutes" : "minute",
|
||||
seconds > 0
|
||||
? String.format(" %1$d %2$s",
|
||||
seconds,
|
||||
seconds > 1 ? "seconds" : "second")
|
||||
: "")
|
||||
: ""
|
||||
);
|
||||
JTextField refreshInterval = new JTextField(interval);
|
||||
refreshInterval.setEditable(false);
|
||||
refreshTimeLabel.setLabelFor(refreshInterval);
|
||||
|
||||
JLabel nextRefreshLabel = new JLabel("Next printer refresh in:");
|
||||
nextRefresh = new JTextField();
|
||||
nextRefresh.setEditable(false);
|
||||
nextRefreshLabel.setLabelFor(nextRefresh);
|
||||
|
||||
JLabel timeoutLabel = new JLabel("Time left:");
|
||||
timeLeft = new JTextField();
|
||||
timeLeft.setEditable(false);
|
||||
@ -317,14 +270,10 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
layout.createSequentialGroup()
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
|
||||
.addComponent(javaLabel)
|
||||
.addComponent(refreshTimeLabel)
|
||||
.addComponent(nextRefreshLabel)
|
||||
.addComponent(timeoutLabel)
|
||||
)
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, true)
|
||||
.addComponent(javaVersion)
|
||||
.addComponent(refreshInterval)
|
||||
.addComponent(nextRefresh)
|
||||
.addComponent(timeLeft)
|
||||
)
|
||||
);
|
||||
@ -334,12 +283,6 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
.addComponent(javaLabel)
|
||||
.addComponent(javaVersion)
|
||||
)
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(refreshTimeLabel)
|
||||
.addComponent(refreshInterval))
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(nextRefreshLabel)
|
||||
.addComponent(nextRefresh))
|
||||
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(timeoutLabel)
|
||||
.addComponent(timeLeft))
|
||||
@ -493,7 +436,6 @@ public class RemotePrinterStatusRefresh extends WindowAdapter {
|
||||
disposeUI();
|
||||
}
|
||||
timeLeft.setText(formatTime(left));
|
||||
nextRefresh.setText(formatTime(refreshTime - (elapsed % refreshTime)));
|
||||
}
|
||||
|
||||
private static String formatTime(final long seconds) {
|
||||
|
||||
60
test/jdk/java/lang/String/concat/IntegerMinValue.java
Normal file
60
test/jdk/java/lang/String/concat/IntegerMinValue.java
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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 8267773
|
||||
* @summary Test
|
||||
*
|
||||
* @compile IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*
|
||||
* @compile -XDstringConcat=inline IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*
|
||||
* @compile -XDstringConcat=indy IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*
|
||||
* @compile -XDstringConcat=indyWithConstants IntegerMinValue.java
|
||||
* @run main/othervm -Xverify:all -Xbatch IntegerMinValue
|
||||
*/
|
||||
|
||||
public class IntegerMinValue {
|
||||
|
||||
public void test() {
|
||||
int i = Integer.MIN_VALUE;
|
||||
String s = "" + i;
|
||||
if (!"-2147483648".equals(s)) {
|
||||
throw new IllegalStateException("Failed: " + s);
|
||||
}
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public static void main(String[] strArr) {
|
||||
IntegerMinValue t = new IntegerMinValue();
|
||||
for (int i = 0; i < 100_000; i++ ) {
|
||||
t.test();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
@ -37,6 +37,7 @@ import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.net.SocketException;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
@ -173,8 +174,8 @@ public class InvalidSSLContextTest {
|
||||
s.startHandshake();
|
||||
s.close();
|
||||
Assert.fail("SERVER: UNEXPECTED ");
|
||||
} catch (SSLException he) {
|
||||
System.out.println("SERVER: caught expected " + he);
|
||||
} catch (SSLException | SocketException se) {
|
||||
System.out.println("SERVER: caught expected " + se);
|
||||
} catch (IOException e) {
|
||||
System.out.println("SERVER: caught: " + e);
|
||||
if (!sslServerSocket.isClosed()) {
|
||||
|
||||
@ -89,10 +89,10 @@ public class TestEnabledProtocols extends SSLSocketTemplate {
|
||||
se.printStackTrace(System.out);
|
||||
} catch (InterruptedIOException ioe) {
|
||||
// must have been interrupted, no harm
|
||||
} catch (SSLException ssle) {
|
||||
} catch (SSLException | SocketException se) {
|
||||
// The client side may have closed the socket.
|
||||
System.out.println("Server SSLException:");
|
||||
ssle.printStackTrace(System.out);
|
||||
se.printStackTrace(System.out);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Server exception:");
|
||||
e.printStackTrace(System.out);
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
* @bug 8189131 8198240 8191844 8189949 8191031 8196141 8204923 8195774 8199779
|
||||
* 8209452 8209506 8210432 8195793 8216577 8222089 8222133 8222137 8222136
|
||||
* 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320
|
||||
* 8243559 8225072 8258630 8259312 8256421
|
||||
* 8243559 8225072 8258630 8259312 8256421 8225081
|
||||
* @summary Check root CA entries in cacerts file
|
||||
*/
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -53,12 +53,12 @@ public class VerifyCACerts {
|
||||
+ File.separator + "security" + File.separator + "cacerts";
|
||||
|
||||
// The numbers of certs now.
|
||||
private static final int COUNT = 92;
|
||||
private static final int COUNT = 91;
|
||||
|
||||
// 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
|
||||
= "02:AE:2C:37:34:B1:B1:3D:74:CB:99:8B:31:4F:C9:BB:23:51:BB:B3:90:59:47:72:C1:4A:36:DA:97:98:06:01";
|
||||
= "9B:C3:0B:24:D4:26:E4:A9:4F:2C:96:25:06:9B:08:E5:13:5B:0B:33:74:5F:78:DB:BD:91:CD:31:D4:37:07:28";
|
||||
|
||||
// map of cert alias to SHA-256 fingerprint
|
||||
@SuppressWarnings("serial")
|
||||
@ -176,8 +176,6 @@ public class VerifyCACerts {
|
||||
"3B:22:2E:56:67:11:E9:92:30:0D:C0:B1:5A:B9:47:3D:AF:DE:F8:C8:4D:0C:EF:7D:33:17:B4:C1:82:1D:14:36");
|
||||
put("swisssignsilverg2ca [jdk]",
|
||||
"BE:6C:4D:A2:BB:B9:BA:59:B6:F3:93:97:68:37:42:46:C3:C0:05:99:3F:A9:8F:02:0D:1D:ED:BE:D4:8A:81:D5");
|
||||
put("soneraclass2ca [jdk]",
|
||||
"79:08:B4:03:14:C1:38:10:0B:51:8D:07:35:80:7F:FB:FC:F8:51:8A:00:95:33:71:05:BA:38:6B:15:3D:D9:27");
|
||||
put("securetrustca [jdk]",
|
||||
"F1:C1:B5:0A:E5:A2:0D:D8:03:0E:C9:F6:BC:24:82:3D:D3:67:B5:25:57:59:B4:E7:1B:61:FC:E9:F7:37:5D:73");
|
||||
put("xrampglobalca [jdk]",
|
||||
@ -266,8 +264,6 @@ public class VerifyCACerts {
|
||||
add("luxtrustglobalrootca [jdk]");
|
||||
// Valid until: Wed Mar 17 11:33:33 PDT 2021
|
||||
add("quovadisrootca [jdk]");
|
||||
// Valid until: Tue Apr 06 00:29:40 PDT 2021
|
||||
add("soneraclass2ca [jdk]");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
104
test/jdk/sun/security/pkcs11/Cipher/EncryptionPadding.java
Normal file
104
test/jdk/sun/security/pkcs11/Cipher/EncryptionPadding.java
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8261355
|
||||
* @library /test/lib ..
|
||||
* @run main/othervm EncryptionPadding
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.Key;
|
||||
import java.security.Provider;
|
||||
import java.util.Arrays;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class EncryptionPadding extends PKCS11Test {
|
||||
|
||||
private static String transformation = "AES/ECB/PKCS5Padding";
|
||||
private static Key key = new SecretKeySpec(new byte[16], "AES");
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
main(new EncryptionPadding(), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void main(Provider p) throws Exception {
|
||||
testWithInputSize(p, 1);
|
||||
testWithInputSize(p, 15);
|
||||
testWithInputSize(p, 16);
|
||||
testWithInputSize(p, 17);
|
||||
System.out.println("TEST PASS - OK");
|
||||
}
|
||||
|
||||
private static void testWithInputSize(Provider p, int inputSize)
|
||||
throws Exception {
|
||||
testWithInputSize(p, inputSize, false);
|
||||
testWithInputSize(p, inputSize, true);
|
||||
}
|
||||
|
||||
private static void testWithInputSize(Provider p, int inputSize,
|
||||
boolean isByteBuffer) throws Exception {
|
||||
byte[] plainText = new byte[inputSize];
|
||||
Arrays.fill(plainText, (byte)(inputSize & 0xFF));
|
||||
ByteBuffer cipherText =
|
||||
ByteBuffer.allocate(((inputSize / 16 ) + 1) * 16);
|
||||
byte[] tmp;
|
||||
|
||||
Cipher sunPKCS11cipher = Cipher.getInstance(transformation, p);
|
||||
sunPKCS11cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
for (int i = 0; i < ((inputSize - 1) / 16) + 1; i++) {
|
||||
int updateLength = Math.min(inputSize - (16 * i), 16);
|
||||
if (!isByteBuffer) {
|
||||
tmp = sunPKCS11cipher.update(plainText, i * 16,
|
||||
updateLength);
|
||||
if (tmp != null) {
|
||||
cipherText.put(tmp);
|
||||
}
|
||||
} else {
|
||||
ByteBuffer bb = ByteBuffer.allocate(updateLength);
|
||||
bb.put(plainText, i * 16, updateLength);
|
||||
bb.flip();
|
||||
sunPKCS11cipher.update(bb, cipherText);
|
||||
}
|
||||
}
|
||||
if (!isByteBuffer) {
|
||||
tmp = sunPKCS11cipher.doFinal();
|
||||
if (tmp != null) {
|
||||
cipherText.put(tmp);
|
||||
}
|
||||
} else {
|
||||
sunPKCS11cipher.doFinal(ByteBuffer.allocate(0), cipherText);
|
||||
}
|
||||
|
||||
Cipher sunJCECipher = Cipher.getInstance(transformation, "SunJCE");
|
||||
sunJCECipher.init(Cipher.DECRYPT_MODE, key);
|
||||
byte[] sunJCEPlain = sunJCECipher.doFinal(cipherText.array());
|
||||
|
||||
if (!Arrays.equals(plainText, sunJCEPlain)) {
|
||||
throw new Exception("Cross-provider cipher test failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 @@ public class TestKeyFactory extends PKCS11Test {
|
||||
|
||||
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 @@ public class TestKeyFactory extends PKCS11Test {
|
||||
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 @@ public class TestKeyFactory extends PKCS11Test {
|
||||
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).");
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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
|
||||
* @bug 4853305 8023980
|
||||
* @summary Test KeyFactory of the new RSA provider
|
||||
* @author Andreas Sterbenz
|
||||
*/
|
||||
@ -41,6 +41,84 @@ public class TestKeyFactory {
|
||||
|
||||
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,55 +141,78 @@ public class TestKeyFactory {
|
||||
}
|
||||
} 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);
|
||||
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
|
||||
KeySpec rsaSpec3 = new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent());
|
||||
PrivateKey key7 = kf.generatePrivate(rsaSpec3);
|
||||
testKey(key6, key6);
|
||||
testKey(key6, key7);
|
||||
if (key instanceof RSAPrivateKey) {
|
||||
KeySpec rsaSpec3 =
|
||||
new RSAPrivateKeySpec(((RSAPrivateKey)key).getModulus(),
|
||||
((RSAPrivateKey)key).getPrivateExponent());
|
||||
PrivateKey key7 = kf.generatePrivate(rsaSpec3);
|
||||
testKey(key6, key7);
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(KeyFactory kf, Key key) throws Exception {
|
||||
@ -137,6 +238,10 @@ public class TestKeyFactory {
|
||||
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).");
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ public class DebugReportsOneExtraByte {
|
||||
OutputAnalyzer output = ProcessTools.executeTestJvm(
|
||||
"-Dtest.src=" + System.getProperty("test.src"),
|
||||
"-Djavax.net.debug=all", "DebugReportsOneExtraByte", "p");
|
||||
output.shouldContain("WRITE: TLS10 application_data, length = 8");
|
||||
output.shouldContain("WRITE: TLSv1 application_data, length = 8");
|
||||
|
||||
System.out.println("Test Passed.");
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 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
|
||||
@ -131,9 +131,9 @@ public class TrustTrustedCert extends SSLSocketTemplate {
|
||||
sslIS.read();
|
||||
sslOS.write('A');
|
||||
sslOS.flush();
|
||||
} catch (SSLException ssle) {
|
||||
} catch (SSLException | SocketException se) {
|
||||
if (!expectFail) {
|
||||
throw ssle;
|
||||
throw se;
|
||||
} // Otherwise, ignore.
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 8211227
|
||||
* @library /test/lib /javax/net/ssl/templates ../../
|
||||
* @summary Tests for consistency in logging format of TLS Versions
|
||||
* @run main/othervm LoggingFormatConsistency
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test runs in another process so we can monitor the debug
|
||||
* results. The OutputAnalyzer must see correct debug output to return a
|
||||
* success.
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.security.SecurityUtils;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
public class LoggingFormatConsistency extends SSLSocketTemplate {
|
||||
|
||||
LoggingFormatConsistency () {
|
||||
serverAddress = InetAddress.getLoopbackAddress();
|
||||
SecurityUtils.removeFromDisabledTlsAlgs("TLSv1", "TLSv1.1");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length != 0) {
|
||||
// A non-empty set of arguments occurs when the "runTest" argument
|
||||
// is passed to the test via ProcessTools::executeTestJvm.
|
||||
//
|
||||
// This is done because an OutputAnalyzer is unable to read
|
||||
// the output of the current running JVM, and must therefore create
|
||||
// a test JVM. When this case occurs, it will inherit all specified
|
||||
// properties passed to the test JVM - debug flags, tls version, etc.
|
||||
new LoggingFormatConsistency().run();
|
||||
} else {
|
||||
// We are in the test JVM that the test is being ran in.
|
||||
var testSrc = "-Dtest.src=" + System.getProperty("test.src");
|
||||
var javaxNetDebug = "-Djavax.net.debug=all";
|
||||
|
||||
var correctTlsVersionsFormat = new String[]{"TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"};
|
||||
var incorrectTLSVersionsFormat = new String[]{"TLS10", "TLS11", "TLS12", "TLS13"};
|
||||
|
||||
for (var i = 0; i < correctTlsVersionsFormat.length; i++) {
|
||||
var expectedTLSVersion = correctTlsVersionsFormat[i];
|
||||
var incorrectTLSVersion = incorrectTLSVersionsFormat[i];
|
||||
|
||||
System.out.println("TESTING " + expectedTLSVersion);
|
||||
var activeTLSProtocol = "-Djdk.tls.client.protocols=" + expectedTLSVersion;
|
||||
var output = ProcessTools.executeTestJvm(
|
||||
testSrc,
|
||||
activeTLSProtocol,
|
||||
javaxNetDebug,
|
||||
"LoggingFormatConsistency",
|
||||
"runTest"); // Ensuring args.length is greater than 0 when test JVM starts
|
||||
|
||||
if (output.getExitValue() != 0) {
|
||||
throw new RuntimeException("Test JVM process failed. JVM stderr= " + output.getStderr());
|
||||
}
|
||||
|
||||
output.shouldContain(expectedTLSVersion);
|
||||
output.shouldNotContain(incorrectTLSVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCustomizedClientConnection() { return true; }
|
||||
|
||||
@Override
|
||||
protected void runServerApplication(SSLSocket socket) throws Exception {
|
||||
var response = "Hello World!";
|
||||
var out = new DataOutputStream(socket.getOutputStream());
|
||||
try {
|
||||
// We don't need to process the data from the socket
|
||||
// Simply sending a response right away is sufficient
|
||||
// to generate the desired debug output
|
||||
var responseBytes = response.getBytes(UTF_8);
|
||||
|
||||
out.writeBytes("HTTP/1.0 200 OK\r\n");
|
||||
out.writeBytes("Content-Length: " + responseBytes.length + "\r\n");
|
||||
out.writeBytes("Content-Type: text/html\r\n\r\n");
|
||||
out.write(responseBytes);
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
|
||||
out.writeBytes("Content-Type: text/html\r\n\r\n");
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runClientApplication(int serverPort) throws Exception {
|
||||
var context = createClientSSLContext();
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
|
||||
|
||||
var host = serverAddress == null ? "localhost" : serverAddress.getHostAddress();
|
||||
var url = new URL("https://" + host + ":" + serverPort + "/");
|
||||
var httpsConnection = (HttpsURLConnection) url.openConnection();
|
||||
httpsConnection.disconnect();
|
||||
try (var in = new BufferedReader(new InputStreamReader(httpsConnection.getInputStream()))) {
|
||||
// Getting the input stream from the BufferedReader is sufficient to generate the desired debug output
|
||||
// We don't need to process the data
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NameVerifier implements HostnameVerifier {
|
||||
@Override
|
||||
public boolean verify(String s, SSLSession sslSession) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Amazon and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8214339 8259662
|
||||
* @summary When a SocketException is thrown by the underlying layer, It
|
||||
* should be thrown as is and not be transformed to an SSLException.
|
||||
* @library /javax/net/ssl/templates
|
||||
* @run main/othervm SSLSocketShouldThrowSocketException
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
import javax.net.ssl.*;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SSLSocketShouldThrowSocketException extends SSLSocketTemplate {
|
||||
|
||||
boolean handshake;
|
||||
|
||||
private final CountDownLatch clientTerminatedCondition = new CountDownLatch(1);
|
||||
|
||||
SSLSocketShouldThrowSocketException(boolean handshake) {
|
||||
this.handshake = handshake;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCustomizedClientConnection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runServerApplication(SSLSocket socket) throws Exception {
|
||||
clientTerminatedCondition.await(30L, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runClientApplication(int serverPort) throws Exception {
|
||||
Socket baseSocket = new Socket("localhost", serverPort);
|
||||
|
||||
SSLSocketFactory sslsf =
|
||||
(SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
SSLSocket sslSocket = (SSLSocket)
|
||||
sslsf.createSocket(baseSocket, "localhost", serverPort, false);
|
||||
|
||||
if (this.handshake) {
|
||||
testHandshakeClose(baseSocket, sslSocket);
|
||||
} else {
|
||||
testDataClose(baseSocket, sslSocket);
|
||||
}
|
||||
|
||||
clientTerminatedCondition.countDown();
|
||||
|
||||
}
|
||||
|
||||
private void testHandshakeClose(Socket baseSocket, SSLSocket sslSocket) throws Exception {
|
||||
Thread aborter = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
System.err.println("Closing the client socket : " + System.nanoTime());
|
||||
baseSocket.close();
|
||||
} catch (Exception ieo) {
|
||||
ieo.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
aborter.start();
|
||||
|
||||
try {
|
||||
// handshaking
|
||||
System.err.println("Client starting handshake: " + System.nanoTime());
|
||||
sslSocket.startHandshake();
|
||||
throw new Exception("Start handshake did not throw an exception");
|
||||
} catch (SocketException se) {
|
||||
System.err.println("Caught Expected SocketException");
|
||||
}
|
||||
|
||||
aborter.join();
|
||||
}
|
||||
|
||||
private void testDataClose(Socket baseSocket, SSLSocket sslSocket) throws Exception{
|
||||
|
||||
CountDownLatch handshakeCondition = new CountDownLatch(1);
|
||||
|
||||
Thread aborter = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
handshakeCondition.await(10L, TimeUnit.SECONDS);
|
||||
System.err.println("Closing the client socket : " + System.nanoTime());
|
||||
baseSocket.close();
|
||||
} catch (Exception ieo) {
|
||||
ieo.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
aborter.start();
|
||||
|
||||
try {
|
||||
// handshaking
|
||||
System.err.println("Client starting handshake: " + System.nanoTime());
|
||||
sslSocket.startHandshake();
|
||||
handshakeCondition.countDown();
|
||||
System.err.println("Reading data from server");
|
||||
BufferedReader is = new BufferedReader(
|
||||
new InputStreamReader(sslSocket.getInputStream()));
|
||||
String data = is.readLine();
|
||||
throw new Exception("Start handshake did not throw an exception");
|
||||
} catch (SocketException se) {
|
||||
System.err.println("Caught Expected SocketException");
|
||||
}
|
||||
|
||||
aborter.join();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// SocketException should be throws during a handshake phase.
|
||||
(new SSLSocketShouldThrowSocketException(true)).run();
|
||||
// SocketException should be throw during the application data phase.
|
||||
(new SSLSocketShouldThrowSocketException(false)).run();
|
||||
}
|
||||
}
|
||||
@ -31,18 +31,18 @@
|
||||
* @bug 8214339
|
||||
* @summary SSLSocketImpl erroneously wraps SocketException
|
||||
* @library /javax/net/ssl/templates
|
||||
* @run main/othervm SSLExceptionForIOIssue
|
||||
* @run main/othervm SocketExceptionForSocketIssues
|
||||
*/
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
|
||||
public class SSLExceptionForIOIssue implements SSLContextTemplate {
|
||||
public class SocketExceptionForSocketIssues implements SSLContextTemplate {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.err.println("===================================");
|
||||
new SSLExceptionForIOIssue().test();
|
||||
new SocketExceptionForSocketIssues().test();
|
||||
}
|
||||
|
||||
private void test() throws Exception {
|
||||
@ -79,9 +79,9 @@ public class SSLExceptionForIOIssue implements SSLContextTemplate {
|
||||
os.flush();
|
||||
} catch (SSLProtocolException | SSLHandshakeException sslhe) {
|
||||
throw sslhe;
|
||||
} catch (SSLException ssle) {
|
||||
} catch (SocketException se) {
|
||||
// the expected exception, ignore it
|
||||
System.err.println("server exception: " + ssle);
|
||||
System.err.println("server exception: " + se);
|
||||
} finally {
|
||||
if (listenSocket != null) {
|
||||
listenSocket.close();
|
||||
73
test/jdk/sun/util/calendar/zi/Beyond2037.java
Normal file
73
test/jdk/sun/util/calendar/zi/Beyond2037.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 8073446 8262110
|
||||
* @summary Tests DST related beyond the year 2037
|
||||
* @run testng Beyond2037
|
||||
*/
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
@Test
|
||||
public class Beyond2037 {
|
||||
|
||||
@DataProvider
|
||||
Object[][] dstTransition() {
|
||||
return new Object[][] {
|
||||
{"2037/03/08 01:59:59:999", "2037/03/08 01:59:59:999"},
|
||||
{"2037/03/08 02:00:00:000", "2037/03/08 03:00:00:000"},
|
||||
{"2038/03/14 01:59:59:999", "2038/03/14 01:59:59:999"},
|
||||
{"2038/03/14 02:00:00:000", "2038/03/14 03:00:00:000"},
|
||||
{"2099/03/08 01:59:59:999", "2099/03/08 01:59:59:999"},
|
||||
{"2099/03/08 02:00:00:000", "2099/03/08 03:00:00:000"},
|
||||
{"2100/03/14 01:59:59:999", "2100/03/14 01:59:59:999"},
|
||||
{"2100/03/14 02:00:00:000", "2100/03/14 03:00:00:000"},
|
||||
{"8000/03/12 01:59:59:999", "8000/03/12 01:59:59:999"},
|
||||
{"8000/03/12 02:00:00:000", "8000/03/12 03:00:00:000"},
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider="dstTransition")
|
||||
public void testDstTransition(String source, String expected) throws Exception {
|
||||
var timeZone = TimeZone.getTimeZone("America/New_York");
|
||||
var sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS" );
|
||||
sdf.setTimeZone(timeZone);
|
||||
assertEquals(sdf.format(sdf.parse(source)), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOffset() throws Exception {
|
||||
var timeZone = TimeZone.getTimeZone("PST8PDT");
|
||||
var df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
df.setTimeZone(timeZone);
|
||||
var tMilli = df.parse("7681-03-09 03:20:49").getTime();
|
||||
assertEquals(timeZone.getOffset(tMilli), -25200000);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2020, 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
|
||||
@ -43,9 +43,12 @@ import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.KeyStore;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
@ -84,9 +87,31 @@ public class TestRedirectLinks extends JavadocTester {
|
||||
*/
|
||||
@Test
|
||||
public void testRedirects() throws Exception {
|
||||
// first, test to see if access to external URLs is available
|
||||
// This test relies on access to an external resource, which may or may not be
|
||||
// reliably available, depending on the host system configuration and other
|
||||
// networking issues. Therefore, it is disabled by default, unless the system
|
||||
// property "javadoc.dev" is set "true".
|
||||
String property = "javadoc.dev";
|
||||
if (!Boolean.getBoolean(property)) {
|
||||
out.println("Test case disabled by default; "
|
||||
+ "set system property \"" + property + "\" to true to enable it.");
|
||||
return;
|
||||
}
|
||||
|
||||
// test to see if access to external URLs is available, and that the URL uses a redirect
|
||||
|
||||
URL testURL = new URL("http://docs.oracle.com/en/java/javase/11/docs/api/element-list");
|
||||
String testURLHost = testURL.getHost();
|
||||
try {
|
||||
InetAddress testAddr = InetAddress.getByName(testURLHost);
|
||||
out.println("Found " + testURLHost + ": " + testAddr);
|
||||
} catch (UnknownHostException e) {
|
||||
out.println("Setup failed (" + testURLHost + " not found); this test skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean haveRedirectURL = false;
|
||||
Instant start = Instant.now();
|
||||
try {
|
||||
URLConnection conn = testURL.openConnection();
|
||||
conn.connect();
|
||||
@ -107,10 +132,12 @@ public class TestRedirectLinks extends JavadocTester {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
out.println("Exception occurred: " + e);
|
||||
Instant now = Instant.now();
|
||||
out.println("Attempt took " + Duration.between(start, now).toSeconds() + " seconds");
|
||||
}
|
||||
|
||||
if (!haveRedirectURL) {
|
||||
out.println("Setup failed; this test skipped");
|
||||
out.println("Setup failed (no redirect URL); this test skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -119,6 +146,7 @@ public class TestRedirectLinks extends JavadocTester {
|
||||
javadoc("-d", outRedirect,
|
||||
"-sourcepath", testSrc,
|
||||
"-link", apiURL,
|
||||
"-Xdoclint:none",
|
||||
"pkg");
|
||||
checkExit(Exit.OK);
|
||||
checkOutput("pkg/B.html", true,
|
||||
@ -157,16 +185,19 @@ public class TestRedirectLinks extends JavadocTester {
|
||||
new JavacTask(tb)
|
||||
.outdir(libModules)
|
||||
.options("--module-source-path", libSrc.toString(),
|
||||
"--module", "mA,mB")
|
||||
"--module", "mA,mB",
|
||||
"-Xdoclint:none")
|
||||
.run()
|
||||
.writeAll();
|
||||
|
||||
javadoc("-d", libApi.toString(),
|
||||
"--module-source-path", libSrc.toString(),
|
||||
"--module", "mA,mB" );
|
||||
"--module", "mA,mB",
|
||||
"-Xdoclint:none" );
|
||||
|
||||
// start web servers
|
||||
InetAddress localHost = InetAddress.getLocalHost();
|
||||
// use loopback address to avoid any issues if proxy is in use
|
||||
InetAddress localHost = InetAddress.getLoopbackAddress();
|
||||
try {
|
||||
oldServer = HttpServer.create(new InetSocketAddress(localHost, 0), 0);
|
||||
String oldURL = "http:/" + oldServer.getAddress();
|
||||
@ -201,7 +232,8 @@ public class TestRedirectLinks extends JavadocTester {
|
||||
"--module-source-path", src.toString(),
|
||||
"--module-path", libModules.toString(),
|
||||
"-link", "http:/" + oldServer.getAddress(),
|
||||
"--module", "mC" );
|
||||
"--module", "mC",
|
||||
"-Xdoclint:none");
|
||||
|
||||
} finally {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier(prevHostNameVerifier);
|
||||
|
||||
@ -62,7 +62,7 @@ public class CPUInfoTest {
|
||||
"avx512bw", "avx512vl", "sha", "fma",
|
||||
"vzeroupper", "avx512_vpopcntdq", "avx512_vpclmulqdq", "avx512_vaes",
|
||||
"avx512_vnni", "clflush", "clflushopt", "clwb",
|
||||
"avx512_vmbi2", "avx512_vmbi", "hv"
|
||||
"avx512_vbmi2", "avx512_vbmi", "hv"
|
||||
);
|
||||
// @formatter:on
|
||||
// Checkstyle: resume
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user