This commit is contained in:
Jesper Wilhelmsson 2022-01-20 01:18:38 +00:00
commit 4616c13c2f
67 changed files with 1126 additions and 799 deletions

View file

@ -1,5 +1,5 @@
//
// Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
@ -2732,11 +2732,8 @@ bool is_vector_arith_imm_pattern(Node* n, Node* m) {
// Should the matcher clone input 'm' of node 'n'?
bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
// ShiftV src (ShiftCntV con)
// StoreVector (VectorStoreMask src)
// Binary src (Replicate con)
if (is_vshift_con_pattern(n, m) ||
(UseSVE > 0 && m->Opcode() == Op_VectorStoreMask && n->Opcode() == Op_StoreVector) ||
is_vector_arith_imm_pattern(n, m)) {
if (is_vshift_con_pattern(n, m) || is_vector_arith_imm_pattern(n, m)) {
mstack.push(m, Visit);
return true;
}

View file

@ -148,7 +148,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
if (index->is_constant()) {
LIR_Const *constant = index->as_constant_ptr();
if (constant->type() == T_INT) {
large_disp += index->as_jint() << shift;
large_disp += ((intx)index->as_jint()) << shift;
} else {
assert(constant->type() == T_LONG, "should be");
jlong c = index->as_jlong() << shift;
@ -194,7 +194,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
if (large_disp == 0 && index->is_register()) {
return new LIR_Address(base, index, type);
} else {
assert(Address::offset_ok_for_immed(large_disp, 0), "must be");
assert(Address::offset_ok_for_immed(large_disp, shift), "failed for large_disp: " INTPTR_FORMAT " and shift %d", large_disp, shift);
return new LIR_Address(base, large_disp, type);
}
}
@ -204,24 +204,7 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o
int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
int elem_size = type2aelembytes(type);
int shift = exact_log2(elem_size);
LIR_Address* addr;
if (index_opr->is_constant()) {
addr = new LIR_Address(array_opr,
offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
} else {
if (offset_in_bytes) {
LIR_Opr tmp = new_pointer_register();
__ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp);
array_opr = tmp;
offset_in_bytes = 0;
}
addr = new LIR_Address(array_opr,
index_opr,
LIR_Address::scale(type),
offset_in_bytes, type);
}
return addr;
return generate_address(array_opr, index_opr, shift, offset_in_bytes, type);
}
LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -29,6 +29,7 @@
#include "jvm.h"
#include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/cardTableBarrierSet.hpp"
@ -159,8 +160,7 @@ int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
Instruction_aarch64::patch(branch+8, 20, 5, (dest >>= 16) & 0xffff);
assert(target_addr_for_insn(branch) == target, "should be");
instructions = 3;
} else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
} else if (NativeInstruction::is_ldrw_to_zr(address(&insn))) {
// nothing to do
assert(target == 0, "did not expect to relocate target for polling page load");
} else {
@ -283,15 +283,19 @@ address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) {
return address(uint64_t(Instruction_aarch64::extract(insns[0], 20, 5))
+ (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
+ (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
} else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 &&
Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
return 0;
} else {
ShouldNotReachHere();
}
return address(((uint64_t)insn_addr + (offset << 2)));
}
address MacroAssembler::target_addr_for_insn_or_null(address insn_addr, unsigned insn) {
if (NativeInstruction::is_ldrw_to_zr(address(&insn))) {
return 0;
}
return MacroAssembler::target_addr_for_insn(insn_addr, insn);
}
void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod) {
if (acquire) {
lea(rscratch1, Address(rthread, JavaThread::polling_word_offset()));

View file

@ -600,10 +600,15 @@ public:
static bool uses_implicit_null_check(void* address);
static address target_addr_for_insn(address insn_addr, unsigned insn);
static address target_addr_for_insn_or_null(address insn_addr, unsigned insn);
static address target_addr_for_insn(address insn_addr) {
unsigned insn = *(unsigned*)insn_addr;
return target_addr_for_insn(insn_addr, insn);
}
static address target_addr_for_insn_or_null(address insn_addr) {
unsigned insn = *(unsigned*)insn_addr;
return target_addr_for_insn_or_null(insn_addr, insn);
}
// Required platform-specific helpers for Label::patch_instructions.
// They _shadow_ the declarations in AbstractAssembler, which are undefined.

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -315,7 +315,7 @@ void NativeMovRegMem::set_offset(int x) {
void NativeMovRegMem::verify() {
#ifdef ASSERT
address dest = MacroAssembler::target_addr_for_insn(instruction_address());
address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address());
#endif
}
@ -329,7 +329,7 @@ void NativeJump::check_verified_entry_alignment(address entry, address verified_
address NativeJump::jump_destination() const {
address dest = MacroAssembler::target_addr_for_insn(instruction_address());
address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address());
// We use jump to self as the unresolved address which the inline
// cache code (and relocs) know about

View file

@ -302,7 +302,8 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
if (fp() - (abi_minframe_size + ijava_state_size) < sp()) {
int min_frame_slots = (abi_minframe_size + ijava_state_size) / sizeof(intptr_t);
if (fp() - min_frame_slots < sp()) {
return false;
}
// These are hacks to keep us out of trouble.

View file

@ -306,7 +306,8 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false;
}
if (fp() - (z_abi_16_size + z_ijava_state_size) < sp()) {
int min_frame_slots = (z_abi_16_size + z_ijava_state_size) / sizeof(intptr_t);
if (fp() - min_frame_slots < sp()) {
return false;
}
// These are hacks to keep us out of trouble.

View file

@ -192,8 +192,32 @@ LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_o
LIR_Address* addr;
if (index_opr->is_constant()) {
int elem_size = type2aelembytes(type);
addr = new LIR_Address(array_opr,
offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
#ifdef _LP64
jint index = index_opr->as_jint();
jlong disp = offset_in_bytes + (jlong)(index) * elem_size;
if (disp > max_jint) {
// Displacement overflow. Cannot directly use instruction with 32-bit displacement for 64-bit addresses.
// Convert array index to long to do array offset computation with 64-bit values.
index_opr = new_register(T_LONG);
__ move(LIR_OprFact::longConst(index), index_opr);
addr = new LIR_Address(array_opr, index_opr, LIR_Address::scale(type), offset_in_bytes, type);
} else {
addr = new LIR_Address(array_opr, (intx)disp, type);
}
#else
// A displacement overflow can also occur for x86 but that is not a problem due to the 32-bit address range!
// Let's assume an array 'a' and an access with displacement 'disp'. When disp overflows, then "a + disp" will
// always be negative (i.e. underflows the 32-bit address range):
// Let N = 2^32: a + signed_overflow(disp) = a + disp - N.
// "a + disp" is always smaller than N. If an index was chosen which would point to an address beyond N, then
// range checks would catch that and throw an exception. Thus, a + disp < 0 holds which means that it always
// underflows the 32-bit address range:
// unsigned_underflow(a + signed_overflow(disp)) = unsigned_underflow(a + disp - N)
// = (a + disp - N) + N = a + disp
// This shows that we still end up at the correct address with a displacement overflow due to the 32-bit address
// range limitation. This overflow only needs to be handled if addresses can be larger as on 64-bit platforms.
addr = new LIR_Address(array_opr, offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
#endif // _LP64
} else {
#ifdef _LP64
if (index_opr->type() == T_INT) {

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -58,14 +58,15 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
// if we were running Java code when SIGPROF came in.
if (isInJava) {
ucontext_t* uc = (ucontext_t*) ucontext;
frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/],
(address)uc->uc_mcontext.regs->nip);
address pc = (address)uc->uc_mcontext.regs->nip;
if (ret_frame.pc() == NULL) {
if (pc == NULL) {
// ucontext wasn't useful
return false;
}
frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], pc);
if (ret_frame.fp() == NULL) {
// The found frame does not have a valid frame pointer.
// Bail out because this will create big trouble later on, either

View file

@ -2036,19 +2036,19 @@ void GraphBuilder::invoke(Bytecodes::Code code) {
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
if (cha_monomorphic_target != NULL) {
if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
// If CHA is able to bind this invoke then update the class
// to match that class, otherwise klass will refer to the
// interface.
klass = cha_monomorphic_target->holder();
ciInstanceKlass* holder = cha_monomorphic_target->holder();
ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
actual_recv = declared_interface;
// insert a check it's really the expected class.
CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
CheckCast* c = new CheckCast(constraint, receiver, copy_state_for_exception());
c->set_incompatible_class_change_check();
c->set_direct_compare(klass->is_final());
c->set_direct_compare(constraint->is_final());
// pass the result of the checkcast so that the compiler has
// more accurate type info in the inlinee
better_receiver = append_split(c);
dependency_recorder()->assert_unique_implementor(declared_interface, singleton);
} else {
cha_monomorphic_target = NULL; // subtype check against Object is useless
}

View file

@ -3053,6 +3053,7 @@ static int inner_classes_jump_to_outer(const Array<u2>* inner_classes, int inner
static bool inner_classes_check_loop_through_outer(const Array<u2>* inner_classes, int idx, const ConstantPool* cp, int length) {
int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset);
int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);
while (fast != -1 && fast != 0) {
if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) {
return true; // found a circularity
@ -3082,14 +3083,15 @@ bool ClassFileParser::check_inner_classes_circularity(const ConstantPool* cp, in
for (int y = idx + InstanceKlass::inner_class_next_offset; y < length;
y += InstanceKlass::inner_class_next_offset) {
// To maintain compatibility, throw an exception if duplicate inner classes
// entries are found.
// 4347400: make sure there's no duplicate entry in the classes array
if (_major_version >= JAVA_1_5_VERSION) {
guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) ||
_inner_classes->at(idx+1) != _inner_classes->at(y+1) ||
_inner_classes->at(idx+2) != _inner_classes->at(y+2) ||
_inner_classes->at(idx+3) != _inner_classes->at(y+3)),
"Duplicate entry in InnerClasses attribute in class file %s",
CHECK_(true));
}
// Return true if there are two entries with the same inner_class_info_index.
if (_inner_classes->at(y) == _inner_classes->at(idx)) {
return true;
@ -3182,10 +3184,9 @@ u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStrea
inner_classes->at_put(index++, inner_access_flags.as_short());
}
// 4347400: make sure there's no duplicate entry in the classes array
// Also, check for circular entries.
// Check for circular and duplicate entries.
bool has_circularity = false;
if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
if (_need_verify) {
has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0);
if (has_circularity) {
// If circularity check failed then ignore InnerClasses attribute.

View file

@ -303,13 +303,19 @@ u1* ClassPathZipEntry::open_entry(JavaThread* current, const char* name, jint* f
}
// read contents into resource array
int size = (*filesize) + ((nul_terminate) ? 1 : 0);
size_t size = (uint32_t)(*filesize);
if (nul_terminate) {
if (sizeof(size) == sizeof(uint32_t) && size == UINT_MAX) {
return NULL; // 32-bit integer overflow will occur.
}
size++;
}
buffer = NEW_RESOURCE_ARRAY(u1, size);
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
// return result
if (nul_terminate) {
buffer[*filesize] = 0;
buffer[size - 1] = 0;
}
return buffer;
}

View file

@ -116,6 +116,12 @@ void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm,
}
}
void Dependencies::assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) {
check_ctxk(ctxk);
check_unique_implementor(ctxk, uniqk);
assert_common_2(unique_implementor, ctxk, uniqk);
}
void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
check_ctxk(ctxk);
assert_common_1(no_finalizable_subclasses, ctxk);
@ -173,6 +179,13 @@ void Dependencies::assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Kla
assert_common_2(abstract_with_unique_concrete_subtype, ctxk_dv, conck_dv);
}
void Dependencies::assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk) {
check_ctxk(ctxk);
assert(ctxk->is_interface(), "not an interface");
assert(ctxk->implementor() == uniqk, "not a unique implementor");
assert_common_2(unique_implementor, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqk));
}
void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
check_ctxk(ctxk);
check_unique_method(ctxk, uniqm);
@ -580,6 +593,7 @@ const char* Dependencies::_dep_name[TYPE_LIMIT] = {
"abstract_with_unique_concrete_subtype",
"unique_concrete_method_2",
"unique_concrete_method_4",
"unique_implementor",
"no_finalizable_subclasses",
"call_site_target_value"
};
@ -591,6 +605,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = {
2, // abstract_with_unique_concrete_subtype ctxk, k
2, // unique_concrete_method_2 ctxk, m
4, // unique_concrete_method_4 ctxk, m, resolved_klass, resolved_method
2, // unique_implementor ctxk, implementor
1, // no_finalizable_subclasses ctxk
2 // call_site_target_value call_site, method_handle
};
@ -1813,6 +1828,16 @@ Klass* Dependencies::check_unique_concrete_method(InstanceKlass* ctxk,
return NULL;
}
Klass* Dependencies::check_unique_implementor(InstanceKlass* ctxk, Klass* uniqk, NewKlassDepChange* changes) {
assert(ctxk->is_interface(), "sanity");
assert(ctxk->nof_implementors() > 0, "no implementors");
if (ctxk->nof_implementors() == 1) {
assert(ctxk->implementor() == uniqk, "sanity");
return NULL;
}
return ctxk; // no unique implementor
}
// Search for AME.
// There are two version of checks.
// 1) Spot checking version(Classload time). Newly added class is checked for AME.
@ -2062,6 +2087,9 @@ Klass* Dependencies::DepStream::check_new_klass_dependency(NewKlassDepChange* ch
case unique_concrete_method_4:
witness = check_unique_concrete_method(context_type(), method_argument(1), type_argument(2), method_argument(3), changes);
break;
case unique_implementor:
witness = check_unique_implementor(context_type(), type_argument(1), changes);
break;
case no_finalizable_subclasses:
witness = check_has_no_finalizable_subclasses(context_type(), changes);
break;

View file

@ -143,6 +143,9 @@ class Dependencies: public ResourceObj {
// of the analysis.
unique_concrete_method_4, // one unique concrete method under CX
// This dependency asserts that interface CX has a unique implementor class.
unique_implementor, // one unique implementor under CX
// This dependency asserts that no instances of class or it's
// subclasses require finalization registration.
no_finalizable_subclasses,
@ -329,7 +332,10 @@ class Dependencies: public ResourceObj {
assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract");
}
static void check_unique_method(ciKlass* ctxk, ciMethod* m) {
assert(!m->can_be_statically_bound(ctxk->as_instance_klass()), "redundant");
assert(!m->can_be_statically_bound(ctxk->as_instance_klass()) || ctxk->is_interface(), "redundant");
}
static void check_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk) {
assert(ctxk->implementor() == uniqk, "not a unique implementor");
}
void assert_common_1(DepType dept, ciBaseObject* x);
@ -343,9 +349,9 @@ class Dependencies: public ResourceObj {
void assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, ciKlass* conck);
void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm);
void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm, ciKlass* resolved_klass, ciMethod* resolved_method);
void assert_unique_implementor(ciInstanceKlass* ctxk, ciInstanceKlass* uniqk);
void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
#if INCLUDE_JVMCI
private:
static void check_ctxk(Klass* ctxk) {
@ -366,6 +372,7 @@ class Dependencies: public ResourceObj {
void assert_evol_method(Method* m);
void assert_has_no_finalizable_subclasses(Klass* ctxk);
void assert_leaf_type(Klass* ctxk);
void assert_unique_implementor(InstanceKlass* ctxk, InstanceKlass* uniqk);
void assert_unique_concrete_method(Klass* ctxk, Method* uniqm);
void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck);
void assert_call_site_target_value(oop callSite, oop methodHandle);
@ -413,6 +420,7 @@ class Dependencies: public ResourceObj {
static Klass* check_evol_method(Method* m);
static Klass* check_leaf_type(InstanceKlass* ctxk);
static Klass* check_abstract_with_unique_concrete_subtype(InstanceKlass* ctxk, Klass* conck, NewKlassDepChange* changes = NULL);
static Klass* check_unique_implementor(InstanceKlass* ctxk, Klass* uniqk, NewKlassDepChange* changes = NULL);
static Klass* check_unique_concrete_method(InstanceKlass* ctxk, Method* uniqm, NewKlassDepChange* changes = NULL);
static Klass* check_unique_concrete_method(InstanceKlass* ctxk, Method* uniqm, Klass* resolved_klass, Method* resolved_method, KlassDepChange* changes = NULL);
static Klass* check_has_no_finalizable_subclasses(InstanceKlass* ctxk, NewKlassDepChange* changes = NULL);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -123,7 +123,13 @@ void G1DirtyCardQueueSet::enqueue_completed_buffer(BufferNode* cbn) {
// Increment _num_cards before adding to queue, so queue removal doesn't
// need to deal with _num_cards possibly going negative.
size_t new_num_cards = Atomic::add(&_num_cards, buffer_size() - cbn->index());
{
// Perform push in CS. The old tail may be popped while the push is
// observing it (attaching it to the new buffer). We need to ensure it
// can't be reused until the push completes, to avoid ABA problems.
GlobalCounter::CriticalSection cs(Thread::current());
_completed.push(*cbn);
}
if ((new_num_cards > process_cards_threshold()) &&
(_primary_refinement_thread != NULL)) {
_primary_refinement_thread->activate();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -109,7 +109,14 @@ inline traceid JfrTraceIdLoadBarrier::load(const PackageEntry* package) {
inline traceid JfrTraceIdLoadBarrier::load(const ClassLoaderData* cld) {
assert(cld != NULL, "invariant");
return cld->has_class_mirror_holder() ? 0 : set_used_and_get(cld);
if (cld->has_class_mirror_holder()) {
return 0;
}
const Klass* const class_loader_klass = cld->class_loader_klass();
if (class_loader_klass != nullptr && should_tag(class_loader_klass)) {
load_barrier(class_loader_klass);
}
return set_used_and_get(cld);
}
inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass, const Method* method) {

View file

@ -2417,7 +2417,9 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) {
} else {
it->push(&_default_vtable_indices);
}
it->push(&_fields);
// _fields might be written into by Rewriter::scan_method() -> fd.set_has_initialized_final_update()
it->push(&_fields, MetaspaceClosure::_writable);
if (itable_length() > 0) {
itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable();

View file

@ -332,8 +332,10 @@ CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool
CallGenerator* miss_cg = CallGenerator::for_uncommon_trap(callee,
Deoptimization::Reason_class_check, Deoptimization::Action_none);
CallGenerator* cg = CallGenerator::for_guarded_call(holder, miss_cg, hit_cg);
ciKlass* constraint = (holder->is_subclass_of(singleton) ? holder : singleton); // avoid upcasts
CallGenerator* cg = CallGenerator::for_guarded_call(constraint, miss_cg, hit_cg);
if (hit_cg != NULL && cg != NULL) {
dependencies()->assert_unique_implementor(declared_interface, singleton);
dependencies()->assert_unique_concrete_method(declared_interface, cha_monomorphic_target, declared_interface, callee);
return cg;
}

View file

@ -177,6 +177,10 @@ final class KeyProtector {
byte[] encodedParams =
encrInfo.getAlgorithm().getEncodedParams();
if (encodedParams == null) {
throw new IOException("Missing PBE parameters");
}
// parse the PBE parameters into the corresponding spec
AlgorithmParameters pbeParams =
AlgorithmParameters.getInstance("PBE");

View file

@ -107,8 +107,12 @@ public final class OAEPParameters extends AlgorithmParametersSpi {
if (!val.getOID().equals(OID_MGF1)) {
throw new IOException("Only MGF1 mgf is supported");
}
byte[] encodedParams = val.getEncodedParams();
if (encodedParams == null) {
throw new IOException("Missing MGF1 parameters");
}
AlgorithmId params = AlgorithmId.parse(
new DerValue(val.getEncodedParams()));
new DerValue(encodedParams));
mgfSpec = switch (params.getName()) {
case "SHA-1" -> MGF1ParameterSpec.SHA1;
case "SHA-224" -> MGF1ParameterSpec.SHA224;
@ -129,7 +133,12 @@ public final class OAEPParameters extends AlgorithmParametersSpi {
if (!val.getOID().equals(OID_PSpecified)) {
throw new IOException("Wrong OID for pSpecified");
}
p = DerValue.wrap(val.getEncodedParams()).getOctetString();
byte[] encodedParams = val.getEncodedParams();
if (encodedParams == null) {
throw new IOException("Missing pSpecified label");
}
p = DerValue.wrap(encodedParams).getOctetString();
} else {
p = new byte[0];
}

View file

@ -1315,6 +1315,8 @@ public class ObjectInputStream
* <li>each object reference previously deserialized from the stream
* (class is {@code null}, arrayLength is -1),
* <li>each regular class (class is not {@code null}, arrayLength is -1),
* <li>each interface class explicitly referenced in the stream
* (it is not called for interfaces implemented by classes in the stream),
* <li>each interface of a dynamic proxy and the dynamic proxy class itself
* (class is not {@code null}, arrayLength is -1),
* <li>each array is filtered using the array type and length of the array
@ -2071,6 +2073,30 @@ public class ObjectInputStream
totalObjectRefs++;
depth++;
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
if (cl != null) {
// Check that serial filtering has been done on the local class descriptor's superclass,
// in case it does not appear in the stream.
// Find the next super descriptor that has a local class descriptor.
// Descriptors for which there is no local class are ignored.
ObjectStreamClass superLocal = null;
for (ObjectStreamClass sDesc = desc.getSuperDesc(); sDesc != null; sDesc = sDesc.getSuperDesc()) {
if ((superLocal = sDesc.getLocalDesc()) != null) {
break;
}
}
// Scan local descriptor superclasses for a match with the local descriptor of the super found above.
// For each super descriptor before the match, invoke the serial filter on the class.
// The filter is invoked for each class that has not already been filtered
// but would be filtered if the instance had been serialized by this Java runtime.
for (ObjectStreamClass lDesc = desc.getLocalDesc().getSuperDesc();
lDesc != null && lDesc != superLocal;
lDesc = lDesc.getSuperDesc()) {
filterCheck(lDesc.forClass(), -1);
}
}
} finally {
depth--;
}
@ -2529,6 +2555,13 @@ public class ObjectInputStream
throw new InternalError();
}
clear();
// Check that an object follows the TC_EXCEPTION typecode
byte tc = bin.peekByte();
if (tc != TC_OBJECT &&
tc != TC_REFERENCE) {
throw new StreamCorruptedException(
String.format("invalid type code: %02X", tc));
}
return (IOException) readObject0(Object.class, false);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 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,7 +26,12 @@
package java.lang;
import java.io.IOException;
import java.util.Arrays;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.Serial;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import jdk.internal.vm.annotation.IntrinsicCandidate;
/**
@ -106,7 +111,7 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
*/
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, Comparable<StringBuffer>, CharSequence
implements Serializable, Comparable<StringBuffer>, CharSequence
{
/**
@ -116,7 +121,7 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
private transient String toStringCache;
/** use serialVersionUID from JDK 1.0.2 for interoperability */
@java.io.Serial
@Serial
static final long serialVersionUID = 3388685877147921107L;
/**
@ -725,25 +730,25 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
* A flag indicating whether the backing array is shared.
* The value is ignored upon deserialization.
*/
@java.io.Serial
private static final java.io.ObjectStreamField[] serialPersistentFields =
@Serial
private static final ObjectStreamField[] serialPersistentFields =
{
new java.io.ObjectStreamField("value", char[].class),
new java.io.ObjectStreamField("count", Integer.TYPE),
new java.io.ObjectStreamField("shared", Boolean.TYPE),
new ObjectStreamField("value", char[].class),
new ObjectStreamField("count", Integer.TYPE),
new ObjectStreamField("shared", Boolean.TYPE),
};
/**
* The {@code writeObject} method is called to write the state of the {@code StringBuffer} to
* a stream.
* The {@code writeObject} method is called to write the state of the
* {@code StringBuffer} to a stream.
*
* @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
java.io.ObjectOutputStream.PutField fields = s.putFields();
@Serial
private synchronized void writeObject(ObjectOutputStream s)
throws IOException {
ObjectOutputStream.PutField fields = s.putFields();
char[] val = new char[capacity()];
if (isLatin1()) {
StringLatin1.getChars(value, 0, count, val, 0);
@ -757,20 +762,26 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
}
/**
* The {@code readObject} method is called to restore the state of the {@code StringBuffer} from
* a stream.
* The {@code readObject} method is called to restore the state of the
* {@code StringBuffer} from a stream.
*
* @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
java.io.ObjectInputStream.GetField fields = s.readFields();
@Serial
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = s.readFields();
char[] val = (char[])fields.get("value", null);
int c = fields.get("count", 0);
if (c < 0 || c > val.length) {
throw new StreamCorruptedException("count value invalid");
}
initBytes(val, 0, val.length);
count = fields.get("count", 0);
count = c;
// ignore shared field
}
synchronized void getBytes(byte[] dst, int dstBegin, byte coder) {

View file

@ -28,6 +28,10 @@ package java.lang;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serial;
import java.io.StreamCorruptedException;
/**
* A mutable sequence of characters. This class provides an API compatible
@ -90,7 +94,7 @@ public final class StringBuilder
{
/** use serialVersionUID for interoperability */
@java.io.Serial
@Serial
static final long serialVersionUID = 4383685877147921099L;
/**
@ -464,9 +468,8 @@ public final class StringBuilder
* @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
@Serial
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
s.writeInt(count);
char[] val = new char[capacity()];
@ -486,13 +489,16 @@ public final class StringBuilder
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(java.io.ObjectInputStream s)
@Serial
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
count = s.readInt();
int c = s.readInt();
char[] val = (char[]) s.readObject();
if (c < 0 || c > val.length) {
throw new StreamCorruptedException("count value invalid");
}
initBytes(val, 0, val.length);
count = c;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 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
@ -1254,7 +1254,7 @@ public class Hashtable<K,V>
* Reconstitute the Hashtable from a stream (i.e., deserialize it).
*/
@java.io.Serial
private void readObject(java.io.ObjectInputStream s)
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
readHashtable(s);
}
@ -1263,14 +1263,16 @@ public class Hashtable<K,V>
* Perform deserialization of the Hashtable from an ObjectInputStream.
* The Properties class overrides this method.
*/
void readHashtable(java.io.ObjectInputStream s)
void readHashtable(ObjectInputStream s)
throws IOException, ClassNotFoundException {
// Read in the threshold and loadFactor
s.defaultReadObject();
// Validate loadFactor (ignore threshold - it will be re-computed)
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new StreamCorruptedException("Illegal Load: " + loadFactor);
ObjectInputStream.GetField fields = s.readFields();
// Read and validate loadFactor (ignore threshold - it will be re-computed)
float lf = fields.get("loadFactor", 0.75f);
if (lf <= 0 || Float.isNaN(lf))
throw new StreamCorruptedException("Illegal load factor: " + lf);
lf = Math.min(Math.max(0.25f, lf), 4.0f);
// Read the original length of the array and number of elements
int origlength = s.readInt();
@ -1282,13 +1284,13 @@ public class Hashtable<K,V>
// Clamp original length to be more than elements / loadFactor
// (this is the invariant enforced with auto-growth)
origlength = Math.max(origlength, (int)(elements / loadFactor) + 1);
origlength = Math.max(origlength, (int)(elements / lf) + 1);
// Compute new length with a bit of room 5% + 3 to grow but
// no larger than the clamped original length. Make the length
// odd if it's large enough, this helps distribute the entries.
// Guard against the length ending up zero, that's not valid.
int length = (int)((elements + elements / 20) / loadFactor) + 3;
int length = (int)((elements + elements / 20) / lf) + 3;
if (length > elements && (length & 1) == 0)
length--;
length = Math.min(length, origlength);
@ -1300,8 +1302,9 @@ public class Hashtable<K,V>
// Check Map.Entry[].class since it's the nearest public type to
// what we're actually creating.
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length);
Hashtable.UnsafeHolder.putLoadFactor(this, lf);
table = new Entry<?,?>[length];
threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
threshold = (int)Math.min(length * lf, MAX_ARRAY_SIZE + 1);
count = 0;
// Read the number of elements and then all the key/value objects
@ -1315,6 +1318,18 @@ public class Hashtable<K,V>
}
}
// Support for resetting final field during deserializing
private static final class UnsafeHolder {
private UnsafeHolder() { throw new InternalError(); }
private static final jdk.internal.misc.Unsafe unsafe
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long LF_OFFSET
= unsafe.objectFieldOffset(Hashtable.class, "loadFactor");
static void putLoadFactor(Hashtable<?, ?> table, float lf) {
unsafe.putFloat(table, LF_OFFSET, lf);
}
}
/**
* The put method used by readObject. This is provided because put
* is overridable and should not be called in readObject since the

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
@ -25,6 +25,8 @@
package java.util;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@ -1267,12 +1269,12 @@ public class IdentityHashMap<K,V>
* particular order.
*/
@java.io.Serial
private void writeObject(java.io.ObjectOutputStream s)
private void writeObject(ObjectOutputStream s)
throws java.io.IOException {
// Write out and any hidden stuff
// Write out size (number of mappings) and any hidden stuff
s.defaultWriteObject();
// Write out size (number of Mappings)
// Write out size again (maintained for backward compatibility)
s.writeInt(size);
// Write out keys and values (alternating)
@ -1291,18 +1293,20 @@ public class IdentityHashMap<K,V>
* deserializes it).
*/
@java.io.Serial
private void readObject(java.io.ObjectInputStream s)
private void readObject(ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden stuff
s.defaultReadObject();
// Size (number of mappings) is written to the stream twice
// Read first size value and ignore it
s.readFields();
// Read in size (number of Mappings)
// Read second size value, validate and assign to size field
int size = s.readInt();
if (size < 0)
throw new java.io.StreamCorruptedException
("Illegal mappings count: " + size);
int cap = capacity(size);
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap);
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, cap*2);
this.size = size;
init(cap);
// Read the keys and values, and put the mappings in the table

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package java.util.jar;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collection;
@ -366,7 +367,7 @@ public class Attributes implements Map<Object,Object>, Cloneable {
int read(Manifest.FastInputStream is, byte[] lbuf, String filename, int lineNumber) throws IOException {
String name = null, value;
byte[] lastline = null;
ByteArrayOutputStream fullLine = new ByteArrayOutputStream();
int len;
while ((len = is.readLine(lbuf)) != -1) {
@ -392,15 +393,12 @@ public class Attributes implements Map<Object,Object>, Cloneable {
+ Manifest.getErrorPosition(filename, lineNumber) + ")");
}
lineContinued = true;
byte[] buf = new byte[lastline.length + len - 1];
System.arraycopy(lastline, 0, buf, 0, lastline.length);
System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);
fullLine.write(lbuf, 1, len - 1);
if (is.peek() == ' ') {
lastline = buf;
continue;
}
value = new String(buf, 0, buf.length, UTF_8.INSTANCE);
lastline = null;
value = fullLine.toString(UTF_8.INSTANCE);
fullLine.reset();
} else {
while (lbuf[i++] != ':') {
if (i >= len) {
@ -414,8 +412,8 @@ public class Attributes implements Map<Object,Object>, Cloneable {
}
name = new String(lbuf, 0, i - 2, UTF_8.INSTANCE);
if (is.peek() == ' ') {
lastline = new byte[len - i];
System.arraycopy(lbuf, i, lastline, 0, len - i);
fullLine.reset();
fullLine.write(lbuf, i, len - i);
continue;
}
value = new String(lbuf, i, len - i, UTF_8.INSTANCE);

View file

@ -3440,8 +3440,8 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
private static final int countChars(CharSequence seq, int index,
int lengthInCodePoints) {
// optimization
if (lengthInCodePoints == 1 && !Character.isHighSurrogate(seq.charAt(index))) {
assert (index >= 0 && index < seq.length());
if (lengthInCodePoints == 1 && index >= 0 && index < seq.length() &&
!Character.isHighSurrogate(seq.charAt(index))) {
return 1;
}
int length = seq.length();

View file

@ -77,15 +77,18 @@ public class EncryptedPrivateKeyInfo {
* @exception NullPointerException if the <code>encoded</code> is null.
* @exception IOException if error occurs when parsing the ASN.1 encoding.
*/
public EncryptedPrivateKeyInfo(byte[] encoded)
throws IOException {
public EncryptedPrivateKeyInfo(byte[] encoded) throws IOException {
if (encoded == null) {
throw new NullPointerException("the encoded parameter " +
"must be non-null");
}
this.encoded = encoded.clone();
DerValue val = new DerValue(this.encoded);
DerValue val = new DerValue(encoded);
if (val.tag != DerValue.tag_Sequence) {
throw new IOException("DER header error: no SEQ tag");
}
this.encoded = encoded.clone();
DerValue[] seq = new DerValue[2];
seq[0] = val.data.getDerValue();

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
@ -127,7 +127,9 @@ public class ContentInfo {
if (oldStyle) {
// JDK1.1.x-style encoding
if (typeAndContent.length > 1) { // content is OPTIONAL
content = typeAndContent[1];
}
} else {
// This is the correct, standards-compliant encoding.
// Parse the content (OPTIONAL field).

View file

@ -383,8 +383,15 @@ public class SignerInfo implements DerEncoder {
if (digestAlgName.equals("SHAKE256")
|| digestAlgName.equals("SHAKE256-LEN")) {
if (digestAlgName.equals("SHAKE256-LEN")) {
int v = new DerValue(digestAlgorithmId
.getEncodedParams()).getInteger();
// RFC8419: for EdDSA in CMS, the id-shake256-len
// algorithm id must contain parameter value 512
// encoded as a positive integer value
byte[] params = digestAlgorithmId.getEncodedParams();
if (params == null) {
throw new SignatureException(
"id-shake256-len oid missing length");
}
int v = new DerValue(params).getInteger();
if (v != 512) {
throw new SignatureException(
"Unsupported id-shake256-" + v);
@ -527,6 +534,7 @@ public class SignerInfo implements DerEncoder {
if (spec == null) {
throw new NoSuchAlgorithmException("Missing PSSParameterSpec for RSASSA-PSS algorithm");
}
if (!AlgorithmId.get(spec.getDigestAlgorithm()).equals(digAlgId)) {
throw new NoSuchAlgorithmException("Incompatible digest algorithm");
}

View file

@ -102,8 +102,13 @@ public final class PSSParameters extends AlgorithmParametersSpi {
if (!val.getOID().equals(AlgorithmId.MGF1_oid)) {
throw new IOException("Only MGF1 mgf is supported");
}
byte[] encodedParams = val.getEncodedParams();
if (encodedParams == null) {
throw new IOException("Missing MGF1 parameters");
}
AlgorithmId params = AlgorithmId.parse(
new DerValue(val.getEncodedParams()));
new DerValue(encodedParams));
String mgfDigestName = params.getName();
switch (mgfDigestName) {
case "SHA-1":

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,8 +32,6 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnixDomainSocketAddress;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.*;
import java.nio.channels.*;
@ -164,10 +162,6 @@ class PipeImpl
try {
if (ssc != null)
ssc.close();
if (sa instanceof UnixDomainSocketAddress) {
Path path = ((UnixDomainSocketAddress) sa).getPath();
Files.deleteIfExists(path);
}
} catch (IOException e2) {}
}
}
@ -184,8 +178,7 @@ class PipeImpl
/**
* Creates Pipe implementation that supports optionally buffering.
*
* @implNote The pipe uses Unix domain sockets where possible. It uses a
* loopback connection on older editions of Windows. When buffering is
* @implNote Uses a loopback connection. When buffering is
* disabled then it sets TCP_NODELAY on the sink channel.
*/
@SuppressWarnings("removal")
@ -212,23 +205,8 @@ class PipeImpl
return sink;
}
private static volatile boolean noUnixDomainSockets;
private static ServerSocketChannel createListener() throws IOException {
ServerSocketChannel listener = null;
if (!noUnixDomainSockets) {
try {
listener = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
return listener.bind(null);
} catch (UnsupportedOperationException | IOException e) {
// IOException is most likely to be caused by the temporary directory
// name being too long. Possibly should log this.
noUnixDomainSockets = true;
if (listener != null)
listener.close();
}
}
listener = ServerSocketChannel.open();
ServerSocketChannel listener = ServerSocketChannel.open();
InetAddress lb = InetAddress.getLoopbackAddress();
listener.bind(new InetSocketAddress(lb, 0));
return listener;

View file

@ -52,6 +52,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
@ -223,6 +224,33 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
}
}
private void readColorPalette(int sizeOfPalette) throws IOException {
final int UNIT_SIZE = 1024000;
if (sizeOfPalette < UNIT_SIZE) {
palette = new byte[sizeOfPalette];
iis.readFully(palette, 0, sizeOfPalette);
} else {
int bytesToRead = sizeOfPalette;
int bytesRead = 0;
List<byte[]> bufs = new ArrayList<>();
while (bytesToRead != 0) {
int sz = Math.min(bytesToRead, UNIT_SIZE);
byte[] unit = new byte[sz];
iis.readFully(unit, 0, sz);
bufs.add(unit);
bytesRead += sz;
bytesToRead -= sz;
}
byte[] paletteData = new byte[bytesRead];
int copiedBytes = 0;
for (byte[] ba : bufs) {
System.arraycopy(ba, 0, paletteData, copiedBytes, ba.length);
copiedBytes += ba.length;
}
palette = paletteData;
}
}
/**
* Process the image header.
*
@ -305,8 +333,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
// Read in the palette
int numberOfEntries = (int)((bitmapOffset - 14 - size) / 3);
int sizeOfPalette = numberOfEntries*3;
palette = new byte[sizeOfPalette];
iis.readFully(palette, 0, sizeOfPalette);
readColorPalette(sizeOfPalette);
metadata.palette = palette;
metadata.paletteSize = numberOfEntries;
} else {
@ -343,8 +370,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
}
int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries * 4;
palette = new byte[sizeOfPalette];
iis.readFully(palette, 0, sizeOfPalette);
readColorPalette(sizeOfPalette);
metadata.palette = palette;
metadata.paletteSize = numberOfEntries;
@ -404,8 +430,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
if (colorsUsed != 0) {
// there is a palette
sizeOfPalette = (int)colorsUsed*4;
palette = new byte[sizeOfPalette];
iis.readFully(palette, 0, sizeOfPalette);
readColorPalette(sizeOfPalette);
metadata.palette = palette;
metadata.paletteSize = (int)colorsUsed;
@ -430,8 +455,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
// Read in the palette
int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries*4;
palette = new byte[sizeOfPalette];
iis.readFully(palette, 0, sizeOfPalette);
readColorPalette(sizeOfPalette);
metadata.palette = palette;
metadata.paletteSize = numberOfEntries;
@ -529,8 +553,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
// Read in the palette
int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries*4;
palette = new byte[sizeOfPalette];
iis.readFully(palette, 0, sizeOfPalette);
readColorPalette(sizeOfPalette);
metadata.palette = palette;
metadata.paletteSize = numberOfEntries;
@ -592,7 +615,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
}
if (metadata.compression == BI_RGB) {
long imageDataSize = (width * height * (bitsPerPixel / 8));
long imageDataSize = ((long)width * height * (bitsPerPixel / 8));
if (imageDataSize > (bitmapFileSize - bitmapOffset)) {
throw new IIOException(I18N.getString("BMPImageReader9"));
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,8 @@ package com.sun.imageio.plugins.common;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import javax.imageio.stream.ImageInputStream;
/**
@ -213,4 +215,47 @@ public class ReaderUtil {
}
return result;
}
/**
* An utility method to allocate and initialize a byte array
* step by step with pre-defined limit, instead of allocating
* a large array up-front based on the length derived from
* an image header.
*
* @param iis a {@code ImageInputStream} to decode data and store
* it in byte array.
* @param length the size of data to decode
*
* @return array of size length when decode succeeeds
*
* @throws IOException if decoding of stream fails
*/
public static byte[] staggeredReadByteStream(ImageInputStream iis,
int length) throws IOException {
final int UNIT_SIZE = 1024000;
byte[] decodedData;
if (length < UNIT_SIZE) {
decodedData = new byte[length];
iis.readFully(decodedData, 0, length);
} else {
int bytesToRead = length;
int bytesRead = 0;
List<byte[]> bufs = new ArrayList<>();
while (bytesToRead != 0) {
int sz = Math.min(bytesToRead, UNIT_SIZE);
byte[] unit = new byte[sz];
iis.readFully(unit, 0, sz);
bufs.add(unit);
bytesRead += sz;
bytesToRead -= sz;
}
decodedData = new byte[bytesRead];
int copiedBytes = 0;
for (byte[] ba : bufs) {
System.arraycopy(ba, 0, decodedData, copiedBytes, ba.length);
copiedBytes += ba.length;
}
}
return decodedData;
}
}

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
@ -1007,6 +1007,11 @@ public class GIFImageReader extends ImageReader {
}
}
if (tableIndex >= prefix.length) {
throw new IIOException("Code buffer limit reached,"
+ " no End of Image tag present, possibly data is corrupted. ");
}
int ti = tableIndex;
int oc = oldCode;

View file

@ -1156,6 +1156,13 @@ public class JPEGImageReader extends ImageReader {
throw new IIOException("Unsupported Image Type");
}
if ((long)width * height > Integer.MAX_VALUE - 2) {
// We are not able to properly decode image that has number
// of pixels greater than Integer.MAX_VALUE - 2
throw new IIOException("Can not read image of the size "
+ width + " by " + height);
}
image = getDestination(param, imageTypes, width, height);
imRas = image.getRaster();

View file

@ -1415,6 +1415,13 @@ public class PNGImageReader extends ImageReader {
int width = metadata.IHDR_width;
int height = metadata.IHDR_height;
if ((long)width * height > Integer.MAX_VALUE - 2) {
// We are not able to properly decode image that has number
// of pixels greater than Integer.MAX_VALUE - 2
throw new IIOException("Can not read image of the size "
+ width + " by " + height);
}
// Init default values
sourceXSubsampling = 1;
sourceYSubsampling = 1;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1438,7 +1438,11 @@ public abstract class TIFFDecompressor {
*
* @param byteCount the number of bytes of compressed data.
*/
public void setByteCount(int byteCount) {
public void setByteCount(int byteCount) throws IOException{
if (byteCount < 0) {
throw new IIOException("Strip byte count can't be"
+ " negative: " + byteCount);
}
this.byteCount = byteCount;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@ import java.io.EOFException;
import javax.imageio.IIOException;
import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
import javax.imageio.plugins.tiff.TIFFField;
import com.sun.imageio.plugins.common.ReaderUtil;
class TIFFFaxDecompressor extends TIFFDecompressor {
@ -637,14 +638,14 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
this.bitsPerScanline = scanlineStride*8;
this.lineBitNum = 8*dstOffset;
this.data = new byte[byteCount];
this.bitPointer = 0;
this.bytePointer = 0;
this.prevChangingElems = new int[w + 1];
this.currChangingElems = new int[w + 1];
stream.seek(offset);
stream.readFully(data);
this.data = ReaderUtil.
staggeredReadByteStream(stream, byteCount);
if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) {
decodeRLE();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@ package com.sun.imageio.plugins.tiff;
import java.io.IOException;
import javax.imageio.IIOException;
import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
import com.sun.imageio.plugins.common.ReaderUtil;
class TIFFLZWDecompressor extends TIFFDecompressor {
@ -95,9 +96,8 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
}
stream.seek(offset);
byte[] sdata = new byte[byteCount];
stream.readFully(sdata);
byte[] sdata = ReaderUtil.
staggeredReadByteStream(stream, byteCount);
if (flipBits) {
for (int i = 0; i < byteCount; i++) {

View file

@ -136,12 +136,7 @@ public class TIFFNullDecompressor extends TIFFDecompressor {
int lastRow = activeSrcHeight - 1;
for (int y = 0; y < activeSrcHeight; y++) {
int bytesRead = stream.read(b, dstOffset, activeBytesPerRow);
if (bytesRead < 0) {
throw new EOFException();
} else if (bytesRead != activeBytesPerRow) {
break;
}
stream.readFully(b, dstOffset, activeBytesPerRow);
dstOffset += scanlineStride;
// Skip unneeded bytes (row suffix + row prefix).
@ -154,17 +149,10 @@ public class TIFFNullDecompressor extends TIFFDecompressor {
stream.seek(offset);
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
if(bytesPerRow == scanlineStride) {
if (stream.read(b, dstOffset, bytesPerRow*srcHeight) < 0) {
throw new EOFException();
}
stream.readFully(b, dstOffset, bytesPerRow*srcHeight);
} else {
for (int y = 0; y < srcHeight; y++) {
int bytesRead = stream.read(b, dstOffset, bytesPerRow);
if (bytesRead < 0) {
throw new EOFException();
} else if (bytesRead != bytesPerRow) {
break;
}
stream.readFully(b, dstOffset, bytesPerRow);
dstOffset += scanlineStride;
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package com.sun.imageio.plugins.tiff;
import java.io.IOException;
import com.sun.imageio.plugins.common.ReaderUtil;
public class TIFFPackBitsDecompressor extends TIFFDecompressor {
@ -77,8 +78,8 @@ public class TIFFPackBitsDecompressor extends TIFFDecompressor {
int scanlineStride) throws IOException {
stream.seek(offset);
byte[] srcData = new byte[byteCount];
stream.readFully(srcData);
byte[] srcData = ReaderUtil.
staggeredReadByteStream(stream, byteCount);
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
byte[] buf;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -180,7 +180,7 @@ public class TIFFYCbCrDecompressor extends TIFFDecompressor {
super.setOffset(offset);
}
public void setByteCount(int byteCount) {
public void setByteCount(int byteCount) throws IOException {
if(decompressor != null) {
decompressor.setByteCount(byteCount);
}

View file

@ -379,6 +379,10 @@ final class SMFParser {
// meta
int metaType = readUnsigned();
int metaLength = (int) readVarInt();
if (metaLength < 0) {
throw new InvalidMidiDataException("length out of bounds: "
+ metaLength);
}
final byte[] metaData;
try {
metaData = new byte[metaLength];

View file

@ -73,6 +73,10 @@ public final class WaveFloatFileReader extends SunFileReader {
samplerate = chunk.readUnsignedInt();
/* framerate = */chunk.readUnsignedInt();
framesize = chunk.readUnsignedShort();
if (framesize == 0) {
throw new UnsupportedAudioFileException(
"Can not process audio format with 0 frame size");
}
bits = chunk.readUnsignedShort();
}
if (chunk.getFormat().equals("data")) {

View file

@ -503,7 +503,9 @@ public class TrueTypeFont extends FileFont {
/* checksum */ ibuffer.get();
table.offset = ibuffer.get() & 0x7FFFFFFF;
table.length = ibuffer.get() & 0x7FFFFFFF;
if (table.offset + table.length > fileSize) {
if ((table.offset + table.length < table.length) ||
(table.offset + table.length > fileSize))
{
throw new FontFormatException("bad table, tag="+table.tag);
}
}
@ -798,8 +800,11 @@ public class TrueTypeFont extends FileFont {
break;
}
}
if (entry == null || entry.length == 0 ||
entry.offset+entry.length > fileSize) {
(entry.offset + entry.length < entry.length) ||
(entry.offset + entry.length > fileSize))
{
return null;
}
@ -888,6 +893,9 @@ public class TrueTypeFont extends FileFont {
return false;
}
ByteBuffer eblcTable = getTableBuffer(EBLCTag);
if (eblcTable == null) {
return false;
}
int numSizes = eblcTable.getInt(4);
/* The bitmapSizeTable's start at offset of 8.
* Each bitmapSizeTable entry is 48 bytes.

View file

@ -39,7 +39,7 @@ import jdk.xml.internal.SecuritySupport;
/**
* @author Morten Jorgensen
* @LastModified: May 2021
* @LastModified: Sept 2021
*/
public final class LoadDocument {
@ -190,6 +190,9 @@ public final class LoadDocument {
if (cache != null) {
newdom = cache.retrieveDocument(base, originalUri, translet);
if (newdom == null) {
if (translet.getAccessError() != null) {
throw new Exception(translet.getAccessError());
}
final Exception e = new FileNotFoundException(originalUri);
throw new TransletException(e);
}

View file

@ -54,7 +54,7 @@ import org.w3c.dom.Document;
* @author Morten Jorgensen
* @author G. Todd Miller
* @author John Howard, JohnH@schemasoft.com
* @LastModified: May 2021
* @LastModified: Sept 2021
*/
public abstract class AbstractTranslet implements Translet {
@ -116,6 +116,9 @@ public abstract class AbstractTranslet implements Translet {
*/
private String _accessExternalStylesheet = JdkConstants.EXTERNAL_ACCESS_DEFAULT;
// The error message when access to exteranl resources is rejected
private String _accessErr = null;
/************************************************************************
* Debugging
************************************************************************/
@ -786,6 +789,20 @@ public abstract class AbstractTranslet implements Translet {
_accessExternalStylesheet = protocols;
}
/**
* Returns the access error.
*/
public String getAccessError() {
return _accessErr;
}
/**
* Sets the access error.
*/
public void setAccessError(String accessErr) {
this._accessErr = accessErr;
}
/************************************************************************
* DOMImplementation caching for basis library
************************************************************************/

View file

@ -101,7 +101,7 @@ import org.xml.sax.ext.LexicalHandler;
* @author Morten Jorgensen
* @author G. Todd Miller
* @author Santiago Pericas-Geertsen
* @LastModified: June 2021
* @LastModified: Sept 2021
*/
public final class TransformerImpl extends Transformer
implements DOMCache
@ -1351,8 +1351,33 @@ public final class TransformerImpl extends Transformer
}
if (resolvedSource == null) {
StreamSource streamSource = new StreamSource(
SystemIDResolver.getAbsoluteURI(href, baseURI));
/**
* Uses the translet to carry over error msg.
* Performs the access check without any interface changes
* (e.g. Translet and DOMCache).
*/
@SuppressWarnings("unchecked") //AbstractTranslet is the sole impl.
AbstractTranslet t = (AbstractTranslet)translet;
String systemId = SystemIDResolver.getAbsoluteURI(href, baseURI);
String errMsg = null;
try {
String accessError = SecuritySupport.checkAccess(systemId,
t.getAllowedProtocols(),
JdkConstants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
ErrorMsg msg = new ErrorMsg(ErrorMsg.ACCESSING_XSLT_TARGET_ERR,
SecuritySupport.sanitizePath(href), accessError);
errMsg = msg.toString();
}
} catch (IOException ioe) {
errMsg = ioe.getMessage();
}
if (errMsg != null) {
t.setAccessError(errMsg);
return null;
}
StreamSource streamSource = new StreamSource(systemId);
return getDOM(streamSource) ;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -54,7 +54,7 @@ import com.sun.org.apache.xerces.internal.xni.XNIException;
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
* @author Eric Ye, IBM
*
* @LastModified: Aug 2021
*/
public class XML11DocumentScannerImpl
extends XMLDocumentScannerImpl {
@ -278,16 +278,6 @@ public class XML11DocumentScannerImpl
+ fStringBuffer.toString() + "\"");
}
}
// note that none of these characters should ever get through
// XML11EntityScanner. Not sure why
// this check was originally necessary. - NG
else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
fEntityScanner.scanChar(null);
fStringBuffer.append(' ');
if (entityDepth == fEntityDepth) {
fStringBuffer2.append('\n');
}
}
else if (c != -1 && XMLChar.isHighSurrogate(c)) {
fStringBuffer3.clear();
if (scanSurrogates(fStringBuffer3)) {

View file

@ -21,6 +21,7 @@
package com.sun.org.apache.xerces.internal.impl;
import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_1;
import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.XML11Char;
@ -40,7 +41,7 @@ import java.io.IOException;
* @author Michael Glavassevich, IBM
* @author Neil Graham, IBM
*
* @LastModified: Apr 2021
* @LastModified: Aug 2021
*/
public class XML11EntityScanner
@ -116,7 +117,7 @@ public class XML11EntityScanner
load(1, false, false);
offset = 0;
}
if (c == '\r' && external) {
if (c == '\r' && external && fCurrentEntity.position < fCurrentEntity.count) {
int cc = fCurrentEntity.ch[fCurrentEntity.position++];
if (cc != '\n' && cc != 0x85) {
fCurrentEntity.position--;
@ -761,71 +762,12 @@ public class XML11EntityScanner
}
// normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
boolean counted = false;
boolean external = fCurrentEntity.isExternal();
if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if ((c == '\r' ) && external) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) {
counted = true;
break;
}
}
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == '\n' || cc == 0x85) {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
}
else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) {
counted = true;
break;
}
}
}
else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
for (int i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(null, fCurrentEntity, offset, length);
content.setValues(fCurrentEntity.ch, offset, length);
if (normalizeNewlines(XML_VERSION_1_1, content, false, false, null)) {
return -1;
}
}
int c;
boolean external = fCurrentEntity.isExternal();
// inner loop, scanning for content
if (external) {
while (fCurrentEntity.position < fCurrentEntity.count) {
@ -913,65 +855,12 @@ public class XML11EntityScanner
}
// normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
boolean external = fCurrentEntity.isExternal();
if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if ((c == '\r' ) && external) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) {
break;
}
}
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == '\n' || cc == 0x85) {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
}
else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) {
break;
}
}
}
else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
for (int i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
content.setValues(fCurrentEntity.ch, offset, length);
if (normalizeNewlines(XML_VERSION_1_1, content, false, true, null)) {
return -1;
}
}
int c;
boolean external = fCurrentEntity.isExternal();
// scan literal value
if (external) {
while (fCurrentEntity.position < fCurrentEntity.count) {
@ -1093,66 +982,11 @@ public class XML11EntityScanner
}
// normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if ((c == '\r' ) && external) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines;
if (load(newlines, false, true)) {
break;
}
}
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == '\n' || cc == 0x85) {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
}
else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
fCurrentEntity.position = newlines;
fCurrentEntity.startPosition = newlines;
fCurrentEntity.count = newlines;
if (load(newlines, false, true)) {
break;
}
}
}
else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
for (int i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length);
if (normalizeNewlines(XML_VERSION_1_1, buffer, true, false, NameType.COMMENT)) {
return true;
}
}
int c;
// iterate over buffer looking for delimiter
OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++];
@ -1256,22 +1090,6 @@ public class XML11EntityScanner
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
}
else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) {
// handle newlines
if (fCurrentEntity.position == fCurrentEntity.count) {
invokeListeners(1);
fCurrentEntity.ch[0] = (char)cc;
load(1, false, false);
}
int ccc = fCurrentEntity.ch[++fCurrentEntity.position];
if (ccc == '\n' || ccc == 0x85) {
fCurrentEntity.position++;
}
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
}
// character was not skipped
return false;

View file

@ -91,7 +91,7 @@ import org.xml.sax.InputSource;
* @author K.Venugopal SUN Microsystems
* @author Neeraj Bajaj SUN Microsystems
* @author Sunitha Reddy SUN Microsystems
* @LastModified: May 2021
* @LastModified: Aug 2021
*/
public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
@ -1235,7 +1235,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
externalEntity = (Entity.ExternalEntity)entity;
extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
expandedSystemId = expandSystemId(extLitSysId, extBaseSysId);
expandedSystemId = expandSystemId(extLitSysId, extBaseSysId, fStrictURI);
boolean unparsed = entity.isUnparsed();
boolean parameter = entityName.startsWith("%");
boolean general = !parameter;
@ -1312,9 +1312,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
*/
xmlInputSource = staxInputSource.getXMLInputSource() ;
if (!fISCreatedByResolver) {
//let the not-LoadExternalDTD or not-SupportDTD process to handle the situation
if (fLoadExternalDTD) {
String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, JdkConstants.ACCESS_EXTERNAL_ALL);
String accessError = SecuritySupport.checkAccess(expandedSystemId,
fAccessExternalDTD, JdkConstants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
fErrorReporter.reportError(this.getEntityScanner(),XMLMessageFormatter.XML_DOMAIN,
"AccessExternalEntity",
@ -1323,7 +1322,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
}
}
}
}
// wrap internal entity
else {
Entity.InternalEntity internalEntity = (Entity.InternalEntity)entity;

View file

@ -21,6 +21,8 @@
package com.sun.org.apache.xerces.internal.impl;
import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_0;
import static com.sun.org.apache.xerces.internal.impl.Constants.XML_VERSION_1_1;
import com.sun.org.apache.xerces.internal.impl.XMLScanner.NameType;
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
@ -55,7 +57,7 @@ import java.util.Locale;
* @author Arnaud Le Hors, IBM
* @author K.Venugopal Sun Microsystems
*
* @LastModified: Apr 2021
* @LastModified: Sep 2021
*/
public class XMLEntityScanner implements XMLLocator {
@ -149,6 +151,15 @@ public class XMLEntityScanner implements XMLLocator {
// indicates that the operation is for detecting XML version
boolean detectingVersion = false;
// offset of the current cursor position
int offset = 0;
// number of newlines in the current process
int newlines = 0;
// indicating whether the content has been counted towards limit
boolean counted = false;
//
// Constructors
//
@ -553,7 +564,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// scan character
int offset = fCurrentEntity.position;
offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\n' || (c == '\r' && isExternal)) {
fCurrentEntity.lineNumber++;
@ -561,10 +572,10 @@ public class XMLEntityScanner implements XMLLocator {
if (fCurrentEntity.position == fCurrentEntity.count) {
invokeListeners(1);
fCurrentEntity.ch[0] = (char)c;
load(1, false, false);
load(1, true, false);
offset = 0;
}
if (c == '\r' && isExternal) {
if (c == '\r' && isExternal && fCurrentEntity.position < fCurrentEntity.count) {
if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
fCurrentEntity.position--;
}
@ -614,7 +625,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// scan nmtoken
int offset = fCurrentEntity.position;
offset = fCurrentEntity.position;
boolean vc = false;
char c;
while (true){
@ -695,7 +706,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// scan name
int offset = fCurrentEntity.position;
offset = fCurrentEntity.position;
int length;
if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
if (++fCurrentEntity.position == fCurrentEntity.count) {
@ -788,7 +799,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// scan qualified name
int offset = fCurrentEntity.position;
offset = fCurrentEntity.position;
//making a check if if the specified character is a valid name start character
//as defined by production [5] in the XML 1.0 specification.
@ -1043,81 +1054,11 @@ public class XMLEntityScanner implements XMLLocator {
}
// normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
boolean counted = false;
if (c == '\n' || (c == '\r' && isExternal)) {
if (DEBUG_BUFFER) {
System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\r' && isExternal) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0;
fCurrentEntity.position = newlines;
if (load(newlines, false, true)) {
counted = true;
break;
}
}
if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
} else if (c == '\n') {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(null, fCurrentEntity, offset, newlines);
offset = 0;
fCurrentEntity.position = newlines;
if (load(newlines, false, true)) {
counted = true;
break;
}
}
} else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
for (int i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(null, fCurrentEntity, offset, length);
//CHANGED: dont replace the value.. append to the buffer. This gives control to the callee
//on buffering the data..
content.setValues(fCurrentEntity.ch, offset, length);
//content.append(fCurrentEntity.ch, offset, length);
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
if (normalizeNewlines(XML_VERSION_1_0, content, false, false, null)) {
return -1;
}
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
}
int c;
while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (!XMLChar.isContent(c)) {
@ -1202,85 +1143,14 @@ public class XMLEntityScanner implements XMLLocator {
}
// normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
if(whiteSpaceInfoNeeded)
whiteSpaceLen=0;
if (c == '\n' || (c == '\r' && isExternal)) {
if (DEBUG_BUFFER) {
System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\r' && isExternal) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.position = newlines;
if (load(newlines, false, true)) {
break;
}
}
if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
/***/
} else if (c == '\n') {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.position = newlines;
if (load(newlines, false, true)) {
break;
}
}
/*** NEWLINE NORMALIZATION ***
* if (fCurrentEntity.ch[fCurrentEntity.position] == '\r'
* && external) {
* fCurrentEntity.position++;
* offset++;
* }
* /***/
} else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
int i=0;
for ( i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
storeWhiteSpace(i);
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
content.setValues(fCurrentEntity.ch, offset, length);
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
if (normalizeNewlines(XML_VERSION_1_0, content, false, true, null)) {
return -1;
}
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
}
int c;
// scan literal value
for (; fCurrentEntity.position<fCurrentEntity.count; fCurrentEntity.position++) {
c = fCurrentEntity.ch[fCurrentEntity.position];
@ -1331,7 +1201,7 @@ public class XMLEntityScanner implements XMLLocator {
*
* @param whiteSpacePos position of a whitespace in the scanner entity buffer
*/
private void storeWhiteSpace(int whiteSpacePos) {
void storeWhiteSpace(int whiteSpacePos) {
if (whiteSpaceLen >= whiteSpaceLookup.length) {
int [] tmp = new int[whiteSpaceLookup.length + 100];
System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length);
@ -1415,75 +1285,11 @@ public class XMLEntityScanner implements XMLLocator {
return false;
}
// normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
if (c == '\n' || (c == '\r' && isExternal)) {
if (DEBUG_BUFFER) {
System.out.print("[newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\r' && isExternal) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.position = newlines;
if (load(newlines, false, true)) {
break;
}
}
if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
} else if (c == '\n') {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
offset = 0;
fCurrentEntity.position = newlines;
fCurrentEntity.count = newlines;
if (load(newlines, false, true)) {
break;
}
}
} else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
for (int i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(NameType.COMMENT, fCurrentEntity, offset, length);
buffer.append(fCurrentEntity.ch, offset, length);
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
if (normalizeNewlines(XML_VERSION_1_0, buffer, true, false, NameType.COMMENT)) {
return true;
}
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
}
int c;
// iterate over buffer looking for delimiter
OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++];
@ -1570,7 +1376,7 @@ public class XMLEntityScanner implements XMLLocator {
}
// skip character
int offset = fCurrentEntity.position;
offset = fCurrentEntity.position;
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == c) {
fCurrentEntity.position++;
@ -1587,26 +1393,6 @@ public class XMLEntityScanner implements XMLLocator {
}
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
} else if (c == '\n' && cc == '\r' && isExternal) {
// handle newlines
if (fCurrentEntity.position == fCurrentEntity.count) {
invokeListeners(1);
fCurrentEntity.ch[0] = (char)cc;
load(1, false, false);
}
fCurrentEntity.position++;
if (fCurrentEntity.ch[fCurrentEntity.position] == '\n') {
fCurrentEntity.position++;
}
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (DEBUG_BUFFER) {
System.out.print(")skipChar, '"+(char)c+"': ");
print();
System.out.println(" -> true");
}
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true;
}
// character was not skipped
@ -1659,7 +1445,7 @@ public class XMLEntityScanner implements XMLLocator {
// skip spaces
int c = fCurrentEntity.ch[fCurrentEntity.position];
int offset = fCurrentEntity.position - 1;
offset = fCurrentEntity.position - 1;
if (XMLChar.isSpace(c)) {
do {
boolean entityChanged = false;
@ -2332,5 +2118,86 @@ public class XMLEntityScanner implements XMLLocator {
} // skipDeclSpaces():boolean
/**
* Normalizes newlines. As specified in XML specification, this method
* converts newlines, '\n', '\r' and '\r\n' to '\n' as 2.11 End-of-Line Handling.
* Further, it may put them in a cache for later process as needed, for example
* as specified in 3.3.3 Attribute-Value Normalization.
*
* @ImplNote this method does not limit to processing external parsed entities
* as 2.11 required. It handles all cases where newlines need to be processed.
*
* @param buffer the current content buffer
* @param append a flag indicating whether to append to the buffer
* @param storeWS a flag indicating whether the whitespaces need to be stored
* for later processing
* @param nt the type of the entity
* @return true if the cursor is at the end of the current entity, false otherwise.
* @throws IOException
*/
protected boolean normalizeNewlines(short version, XMLString buffer, boolean append,
boolean storeWS, NameType nt)
throws IOException {
// normalize newlines
offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
newlines = 0;
// how this information is used is determined by the caller of this method
counted = false;
if ((c == '\n' || c == '\r') ||
(version == XML_VERSION_1_1 && (c == 0x85 || c == 0x2028) && isExternal)) {
do {
c = fCurrentEntity.ch[fCurrentEntity.position++];
if ((c == '\n' || c == '\r') ||
(version == XML_VERSION_1_1 && (c == 0x85 || c == 0x2028))) {
newlines++;
fCurrentEntity.lineNumber++;
fCurrentEntity.columnNumber = 1;
if (fCurrentEntity.position == fCurrentEntity.count) {
checkEntityLimit(nt, fCurrentEntity, offset, newlines);
offset = 0;
fCurrentEntity.position = newlines;
if (load(newlines, false, true)) {
counted = true;
break;
}
}
if (c == '\r') {
int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == '\n' || (version == XML_VERSION_1_1 && cc == 0x85)) {
fCurrentEntity.position++;
offset++;
}
/*** NEWLINE NORMALIZATION ***/
else {
newlines++;
}
}
} else {
fCurrentEntity.position--;
break;
}
} while (fCurrentEntity.position < fCurrentEntity.count - 1);
for (int i = offset; i < fCurrentEntity.position; i++) {
fCurrentEntity.ch[i] = '\n';
if (storeWS) {
storeWhiteSpace(i);
}
}
int length = fCurrentEntity.position - offset;
if (fCurrentEntity.position == fCurrentEntity.count - 1) {
checkEntityLimit(nt, fCurrentEntity, offset, length);
if (append) {
buffer.append(fCurrentEntity.ch, offset, length);
} else {
buffer.setValues(fCurrentEntity.ch, offset, length);
}
return true;
}
}
return false;
}
} // class XMLEntityScanner

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.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -67,7 +67,7 @@ import com.sun.xml.internal.stream.Entity;
* @author Eric Ye, IBM
* @author K.Venugopal SUN Microsystems
* @author Sunitha Reddy, SUN Microsystems
* @LastModified: Feb 2020
* @LastModified: Aug 2021
*/
public abstract class XMLScanner
implements XMLComponent {
@ -956,12 +956,6 @@ public abstract class XMLScanner
System.out.println("** valueF: \""
+ stringBuffer.toString() + "\"");
}
} else if (c == '\n' || c == '\r') {
fEntityScanner.scanChar(null);
stringBuffer.append(' ');
if (entityDepth == fEntityDepth && fNeedNonNormalizedValue) {
fStringBuffer2.append('\n');
}
} else if (c != -1 && XMLChar.isHighSurrogate(c)) {
fStringBuffer3.clear();
if (scanSurrogates(fStringBuffer3)) {

View file

@ -1,6 +1,5 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -41,19 +40,11 @@ import com.sun.org.apache.xerces.internal.xni.XMLString;
*
* @author Andy Clark, IBM
* @author Eric Ye, IBM
*
* @LastModified: Aug 2021
*/
public class XMLStringBuffer
extends XMLString {
//
// Constants
//
/** Default buffer size (32). */
public static final int DEFAULT_SIZE = 32;
//
// Data
//
@ -112,79 +103,4 @@ extends XMLString {
length = 0;
}
/**
* append
*
* @param c
*/
public void append(char c) {
if(this.length + 1 > this.ch.length){
int newLength = this.ch.length * 2 ;
if(newLength < this.ch.length + DEFAULT_SIZE){
newLength = this.ch.length + DEFAULT_SIZE;
}
char [] tmp = new char[newLength];
System.arraycopy(this.ch, 0, tmp, 0, this.length);
this.ch = tmp;
}
this.ch[this.length] = c ;
this.length++;
} // append(char)
/**
* append
*
* @param s
*/
public void append(String s) {
int length = s.length();
if (this.length + length > this.ch.length) {
int newLength = this.ch.length * 2 ;
if(newLength < this.ch.length + length + DEFAULT_SIZE){
newLength = this.ch.length + length+ DEFAULT_SIZE;
}
char[] newch = new char[newLength];
System.arraycopy(this.ch, 0, newch, 0, this.length);
this.ch = newch;
}
s.getChars(0, length, this.ch, this.length);
this.length += length;
} // append(String)
/**
* append
*
* @param ch
* @param offset
* @param length
*/
public void append(char[] ch, int offset, int length) {
if (this.length + length > this.ch.length) {
int newLength = this.ch.length * 2 ;
if(newLength < this.ch.length + length + DEFAULT_SIZE){
newLength = this.ch.length + length + DEFAULT_SIZE;
}
char[] newch = new char[newLength];
System.arraycopy(this.ch, 0, newch, 0, this.length);
this.ch = newch;
}
//making the code more robust as it would handle null or 0 length data,
//add the data only when it contains some thing
if(ch != null && length > 0){
System.arraycopy(ch, offset, this.ch, this.length, length);
this.length += length;
}
} // append(char[],int,int)
/**
* append
*
* @param s
*/
public void append(XMLString s) {
append(s.ch, s.offset, s.length);
} // append(XMLString)
} // class XMLStringBuffer

View file

@ -1,6 +1,5 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -42,9 +41,11 @@ package com.sun.org.apache.xerces.internal.xni;
*
* @author Eric Ye, IBM
* @author Andy Clark, IBM
*
* @LastModified: Aug 2021
*/
public class XMLString {
/** Default buffer size (32). */
public static final int DEFAULT_SIZE = 32;
//
// Data
@ -189,4 +190,78 @@ public class XMLString {
return length > 0 ? new String(ch, offset, length) : "";
} // toString():String
/**
* Appends a char to the buffer.
*
* @param c the char
*/
public void append(char c) {
if(this.length + 1 > this.ch.length){
int newLength = this.ch.length * 2 ;
if(newLength < this.ch.length + DEFAULT_SIZE){
newLength = this.ch.length + DEFAULT_SIZE;
}
char [] tmp = new char[newLength];
System.arraycopy(this.ch, 0, tmp, 0, this.length);
this.ch = tmp;
}
this.ch[this.length] = c ;
this.length++;
} // append(char)
/**
* Appends a string to the buffer.
*
* @param s the string
*/
public void append(String s) {
int length = s.length();
if (this.length + length > this.ch.length) {
int newLength = this.ch.length * 2 ;
if(newLength < this.ch.length + length + DEFAULT_SIZE){
newLength = this.ch.length + length+ DEFAULT_SIZE;
}
char[] newch = new char[newLength];
System.arraycopy(this.ch, 0, newch, 0, this.length);
this.ch = newch;
}
s.getChars(0, length, this.ch, this.length);
this.length += length;
} // append(String)
/**
* Appends a number of characters to the buffer.
*
* @param ch the char array
* @param offset the offset
* @param length the length
*/
public void append(char[] ch, int offset, int length) {
if (this.length + length > this.ch.length) {
int newLength = this.ch.length * 2 ;
if(newLength < this.ch.length + length + DEFAULT_SIZE){
newLength = this.ch.length + length + DEFAULT_SIZE;
}
char[] newch = new char[newLength];
System.arraycopy(this.ch, 0, newch, 0, this.length);
this.ch = newch;
}
//making the code more robust as it would handle null or 0 length data,
//add the data only when it contains some thing
if(ch != null && length > 0){
System.arraycopy(ch, offset, this.ch, this.length, length);
this.length += length;
}
} // append(char[],int,int)
/**
* Appends another buffer to this buffer
*
* @param s another buffer
*/
public void append(XMLString s) {
append(s.ch, s.offset, s.length);
} // append(XMLString)
} // class XMLString

View file

@ -1,6 +1,5 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@ -35,6 +34,8 @@ import com.sun.org.apache.xml.internal.utils.URI.MalformedURIException;
* fact that it's declared to throw TransformerException. Please
* see code comments for details on how resolution is performed.</p>
* @xsl.usage internal
*
* @LastModified: Sept 2021
*/
public class SystemIDResolver
{
@ -275,7 +276,7 @@ public class SystemIDResolver
public static String getAbsoluteURI(String urlString, String base)
throws TransformerException
{
if (base == null)
if (base == null || base.length() == 0)
return getAbsoluteURI(urlString);
String absoluteBase = getAbsoluteURI(base);

View file

@ -27,6 +27,7 @@ package com.sun.java.accessibility.internal;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.util.*;
import java.lang.*;
import java.lang.reflect.*;
@ -478,6 +479,9 @@ public final class AccessBridge {
if (parent == null) {
return null;
}
Point userSpaceXY = AccessibilityGraphicsEnvironment.toUserSpace(x, y);
x = userSpaceXY.x;
y = userSpaceXY.y;
if (windowHandleToContextMap != null &&
windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
// Path for applications that register their top-level
@ -1593,6 +1597,8 @@ public final class AccessBridge {
if (p != null) {
r.x = p.x;
r.y = p.y;
r = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(r);
return r;
}
} catch (Exception e) {
@ -2257,6 +2263,7 @@ public final class AccessBridge {
if (s != null && s.equals("\n")) {
rect.width = 0;
}
rect = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(rect);
return rect;
}
}
@ -7338,4 +7345,182 @@ public final class AccessBridge {
}
}
}
/**
* A helper class to handle coordinate conversion between screen and user spaces.
* See {@link sun.java2d.SunGraphicsEnvironment}
*/
private static abstract class AccessibilityGraphicsEnvironment extends GraphicsEnvironment {
/**
* Returns the graphics configuration which bounds contain the given point in the user's space.
*
* See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)}
*
* @param x the x coordinate of the given point in the user's space
* @param y the y coordinate of the given point in the user's space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(double x, double y) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
return getGraphicsConfigurationAtPoint(gc, x, y);
}
/**
* Returns the graphics configuration which bounds contain the given point in the user's space.
*
* See {@link sun.java2d.SunGraphicsEnvironment#getGraphicsConfigurationAtPoint(GraphicsConfiguration, double, double)}
*
* @param current the default configuration which is checked in the first
* place
* @param x the x coordinate of the given point in the user's space
* @param y the y coordinate of the given point in the user's space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(
GraphicsConfiguration current, double x, double y) {
if (containsUserSpacePoint(current, x, y)) {
return current;
}
GraphicsEnvironment env = getLocalGraphicsEnvironment();
for (GraphicsDevice device : env.getScreenDevices()) {
GraphicsConfiguration config = device.getDefaultConfiguration();
if (containsUserSpacePoint(config, x, y)) {
return config;
}
}
return current;
}
/**
* Returns the graphics configuration which bounds contain the given point in the device space.
*
* @param x the x coordinate of the given point in the device space
* @param y the y coordinate of the given point in the device space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(double x, double y) {
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration();
return getGraphicsConfigurationAtDevicePoint(gc, x, y);
}
/**
* Returns the graphics configuration which bounds contain the given point in the device space.
*
* @param current the default configuration which is checked in the first
* place
* @param x the x coordinate of the given point in the device space
* @param y the y coordinate of the given point in the device space
* @return the graphics configuration
*/
public static GraphicsConfiguration getGraphicsConfigurationAtDevicePoint(
GraphicsConfiguration current, double x, double y) {
if (containsDeviceSpacePoint(current, x, y)) {
return current;
}
GraphicsEnvironment env = getLocalGraphicsEnvironment();
for (GraphicsDevice device : env.getScreenDevices()) {
GraphicsConfiguration config = device.getDefaultConfiguration();
if (containsDeviceSpacePoint(config, x, y)) {
return config;
}
}
return current;
}
private static boolean containsDeviceSpacePoint(GraphicsConfiguration config, double x, double y) {
Rectangle bounds = config.getBounds();
bounds = toDeviceSpaceAbs(config, bounds.x, bounds.y, bounds.width, bounds.height);
return bounds.contains(x, y);
}
private static boolean containsUserSpacePoint(GraphicsConfiguration config, double x, double y) {
Rectangle bounds = config.getBounds();
return bounds.contains(x, y);
}
/**
* Converts absolute coordinates from the device
* space to the user's space space using appropriate device transformation.
*
* @param x absolute x coordinate in the device's space
* @param y absolute y coordinate in the device's space
* @return the corresponding coordinates in user's space
*/
public static Point toUserSpace(int x, int y) {
GraphicsConfiguration gc = getGraphicsConfigurationAtDevicePoint(x, y);
return toUserSpace(gc, x, y);
}
/**
* Converts absolute coordinates from the device
* space to the user's space using passed graphics configuration.
*
* @param gc the graphics configuration to be used for transformation
* @param x absolute x coordinate in the device's space
* @param y absolute y coordinate in the device's space
* @return the corresponding coordinates in user's space
*/
public static Point toUserSpace(GraphicsConfiguration gc, int x, int y) {
AffineTransform tx = gc.getDefaultTransform();
Rectangle screen = gc.getBounds();
int userX = screen.x + clipRound((x - screen.x) / tx.getScaleX());
int userY = screen.y + clipRound((y - screen.y) / tx.getScaleY());
return new Point(userX, userY);
}
/**
* Converts the rectangle from the user's space to the device space using
* appropriate device transformation.
*
* See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(Rectangle)}
*
* @param rect the rectangle in the user's space
* @return the rectangle which uses device space (pixels)
*/
public static Rectangle toDeviceSpaceAbs(Rectangle rect) {
GraphicsConfiguration gc = getGraphicsConfigurationAtPoint(rect.x, rect.y);
return toDeviceSpaceAbs(gc, rect.x, rect.y, rect.width, rect.height);
}
/**
* Converts absolute coordinates (x, y) and the size (w, h) from the user's
* space to the device space using passed graphics configuration.
*
* See {@link sun.java2d.SunGraphicsEnvironment#toDeviceSpaceAbs(GraphicsConfiguration, int, int, int, int)}
*
* @param gc the graphics configuration to be used for transformation
* @param x absolute coordinate in the user's space
* @param y absolute coordinate in the user's space
* @param w the width in the user's space
* @param h the height in the user's space
* @return the rectangle which uses device space (pixels)
*/
public static Rectangle toDeviceSpaceAbs(GraphicsConfiguration gc,
int x, int y, int w, int h) {
AffineTransform tx = gc.getDefaultTransform();
Rectangle screen = gc.getBounds();
return new Rectangle(
screen.x + clipRound((x - screen.x) * tx.getScaleX()),
screen.y + clipRound((y - screen.y) * tx.getScaleY()),
clipRound(w * tx.getScaleX()),
clipRound(h * tx.getScaleY())
);
}
/**
* See {@link sun.java2d.pipe.Region#clipRound}
*/
private static int clipRound(final double coordinate) {
final double newv = coordinate - 0.5;
if (newv < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
if (newv > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return (int) Math.ceil(newv);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -399,6 +399,7 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue
/*
* Setup data to copy to target process
*/
memset(&data, 0, sizeof(data));
data._GetModuleHandle = _GetModuleHandle;
data._GetProcAddress = _GetProcAddress;

View file

@ -665,11 +665,14 @@ public class TransPatterns extends TreeTranslator {
@Override
public void visitClassDef(JCClassDecl tree) {
ClassSymbol prevCurrentClass = currentClass;
MethodSymbol prevMethodSym = currentMethodSym;
try {
currentClass = tree.sym;
currentMethodSym = null;
super.visitClassDef(tree);
} finally {
currentClass = prevCurrentClass;
currentMethodSym = prevMethodSym;
}
}

View file

@ -41,6 +41,9 @@ class FixedLengthInputStream extends LeftOverInputStream {
FixedLengthInputStream (ExchangeImpl t, InputStream src, long len) {
super (t, src);
if (len < 0) {
throw new IllegalArgumentException("Content-Length: " + len);
}
this.remaining = len;
}

View file

@ -47,6 +47,9 @@ class FixedLengthOutputStream extends FilterOutputStream
FixedLengthOutputStream (ExchangeImpl t, OutputStream src, long len) {
super (src);
if (len < 0) {
throw new IllegalArgumentException("Content-Length: " + len);
}
this.t = t;
this.remaining = len;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -208,7 +208,9 @@ class Request {
"sun.net.httpserver.maxReqHeaders) exceeded, " +
ServerConfig.getMaxReqHeaders() + ".");
}
if (k == null) { // Headers disallows null keys, use empty string
k = ""; // instead to represent invalid key
}
hdrs.add (k,v);
len = 0;
}

View file

@ -630,6 +630,11 @@ class ServerImpl implements TimeSource {
headerValue = headers.getFirst("Content-Length");
if (headerValue != null) {
clen = Long.parseLong(headerValue);
if (clen < 0) {
reject(Code.HTTP_BAD_REQUEST, requestLine,
"Illegal Content-Length value");
return;
}
}
if (clen == 0) {
requestCompleted(connection);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 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
@ -100,7 +100,7 @@ public class DeserializedLength {
);
for (int elements : new int[]{10, 50, 500, 5000}) {
for (float loadFactor : new float[]{0.15f, 0.5f, 0.75f, 1.0f, 2.5f}) {
for (float loadFactor : new float[]{0.25f, 0.5f, 0.75f, 1.0f, 2.5f}) {
ok &= testDeserializedLength(elements, loadFactor);
}
}

View file

@ -70,12 +70,17 @@ public class TestMaxSize {
while (directorySize(dir) < 50_000_000) {
emitEvents(500_000);
}
System.out.println("Before setMaxSize(1_000_000)");
fileCount(dir);
e.setMaxSize(1_000_000);
System.out.println("After setMaxSize(1_000_000)");
long count = fileCount(dir);
if (count > 2) {
// Two chunks can happen when header of new chunk is written and previous
// chunk is not finalized.
throw new Exception("Expected only one or two chunks with setMaxSize(1_000_000). Found " + count);
if (count > 3) {
// Three files can happen when:
// File 1: Header of new chunk is written to disk
// File 2: Previous chunk is not yet finalized and added to list of DiskChunks
// File 3: Previous previous file is in the list of DiskChunks.
throw new Exception("Expected at most three chunks with setMaxSize(1_000_000). Found " + count);
}
finished.set(true);
}
@ -94,21 +99,24 @@ public class TestMaxSize {
System.out.println("Files:");
AtomicInteger count = new AtomicInteger();
Files.list(dir).forEach(p -> {
System.out.println(p);
System.out.println(p + " " + fileSize(p));
count.incrementAndGet();
});
return count.get();
}
private static long directorySize(Path dir) throws IOException {
long p = Files.list(dir).mapToLong(f -> {
try {
return Files.size(f);
} catch (IOException e) {
return 0;
}
}).sum();
long p = Files.list(dir).mapToLong(f -> fileSize(f)).sum();
System.out.println("Directory size: " + p);
return p;
}
private static long fileSize(Path p) {
try {
return Files.size(p);
} catch (IOException e) {
System.out.println("Could not determine file size for " + p);
return 0;
}
}
}

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8278834
* @summary Verify pattern matching nested inside initializers of classes nested in methods
* works correctly.
* @library /tools/lib /tools/javac/lib
* @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.main
* jdk.compiler/com.sun.tools.javac.util
* @build toolbox.ToolBox toolbox.JavacTask
* @build combo.ComboTestHelper
* @compile BindingsInitializer.java
* @run main BindingsInitializer
*/
import combo.ComboInstance;
import combo.ComboParameter;
import combo.ComboTask;
import combo.ComboTestHelper;
import java.nio.file.Path;
import java.nio.file.Paths;
import toolbox.ToolBox;
public class BindingsInitializer extends ComboInstance<BindingsInitializer> {
protected ToolBox tb;
BindingsInitializer() {
super();
tb = new ToolBox();
}
public static void main(String... args) throws Exception {
new ComboTestHelper<BindingsInitializer>()
.withDimension("OUTER", (x, outer) -> x.outer = outer, Outer.values())
.withDimension("MIDDLE", (x, middle) -> x.middle = middle, Middle.values())
.withDimension("INNER", (x, inner) -> x.inner = inner, Inner.values())
.withDimension("TEST", (x, test) -> x.test = test, Test.values())
.run(BindingsInitializer::new);
}
private Outer outer;
private Middle middle;
private Inner inner;
private Test test;
private static final String MAIN_TEMPLATE =
"""
public class Test {
private static Object obj = "";
#{OUTER}
}
""";
@Override
protected void doWork() throws Throwable {
Path base = Paths.get(".");
ComboTask task = newCompilationTask()
.withSourceFromTemplate(MAIN_TEMPLATE, pname -> switch (pname) {
case "OUTER" -> outer;
case "MIDDLE" -> middle;
case "INNER" -> inner;
case "TESST" -> test;
default -> throw new UnsupportedOperationException(pname);
});
task.generate(result -> {
if (result.hasErrors()) {
throw new AssertionError("Unexpected result: " + result.compilationInfo());
}
});
}
public enum Outer implements ComboParameter {
NONE("#{MIDDLE}"),
STATIC_CLASS("static class Nested { #{MIDDLE} }"),
CLASS("class Inner { #{MIDDLE} }");
private final String code;
private Outer(String code) {
this.code = code;
}
@Override
public String expand(String optParameter) {
return code;
}
}
public enum Middle implements ComboParameter {
STATIC_INIT("static { #{INNER} }"),
INIT("{ #{INNER} }"),
METHOD("void test() { #{INNER} }");
private final String code;
private Middle(String code) {
this.code = code;
}
@Override
public String expand(String optParameter) {
return code;
}
}
public enum Inner implements ComboParameter {
DIRECT("#{TEST}"),
CLASS_STATIC_INIT("class C { static { #{TEST} } }"),
CLASS_INIT("class C { { #{TEST} } }"),
CLASS_METHOD("class C { void t() { #{TEST} } }"),
ANNONYMOUS_CLASS_STATIC_INIT("new Object() { static { #{TEST} } };"),
ANNONYMOUS_CLASS_INIT("new Object() { { #{TEST} } };"),
ANNONYMOUS_CLASS_METHOD("new Object() { void t() { #{TEST} } };");
private final String code;
private Inner(String code) {
this.code = code;
}
@Override
public String expand(String optParameter) {
return code;
}
}
public enum Test implements ComboParameter {
TEST("if (obj instanceof String str) System.err.println(str);");
private final String code;
private Test(String code) {
this.code = code;
}
@Override
public String expand(String optParameter) {
return code;
}
}
}