This commit is contained in:
Rob McKenna 2021-05-12 12:26:05 +00:00
commit dbb6f4c1ee
53 changed files with 1380 additions and 794 deletions

View File

@ -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=&lt;path&gt;</code> and <code>--with-freetype-lib=&lt;path&gt;</code> if <code>configure</code> does not automatically locate the platform FreeType files.</p>
<h3 id="cups">CUPS</h3>

View File

@ -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.

View File

@ -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])

View File

@ -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 \

View File

@ -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-----

View File

@ -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();
}

View File

@ -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;

View File

@ -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() {

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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.

View File

@ -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) {

View File

@ -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

View File

@ -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()) {

View File

@ -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);

View File

@ -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);
}

View File

@ -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());
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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) {

View File

@ -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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();
}
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -633,7 +633,8 @@ sun.security.krb5.maxReferrals=5
#
#
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & usage TLSServer, \
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224, \
SHA1 jdkCA & usage SignedJAR & denyAfter 2019-01-01
#
# Legacy algorithms for certification path (CertPath) processing and
@ -697,7 +698,7 @@ jdk.security.legacyAlgorithms=SHA1, \
# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
#
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024
DSA keySize < 1024, SHA1 jdkCA & denyAfter 2019-01-01
#
# Algorithm restrictions for Secure Socket Layer/Transport Layer Security

View File

@ -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 */

View File

@ -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;

View File

@ -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();
}

View File

@ -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,

View File

@ -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(),

View File

@ -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

View File

@ -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);
}
}

View File

@ -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
}
}
}

View File

@ -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) {

View File

@ -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()) {

View File

@ -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);

View File

@ -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]");
}
};

View 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.");
}
}
}

View File

@ -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).");
}

View File

@ -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).");
}

View File

@ -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.
}
}

View File

@ -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();
}
}

View File

@ -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();

View 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);
}
}

View File

@ -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);