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. // Copyright (c) 2014, 2021, Red Hat, Inc. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // 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'? // Should the matcher clone input 'm' of node 'n'?
bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
// ShiftV src (ShiftCntV con) // ShiftV src (ShiftCntV con)
// StoreVector (VectorStoreMask src)
// Binary src (Replicate con) // Binary src (Replicate con)
if (is_vshift_con_pattern(n, m) || if (is_vshift_con_pattern(n, m) || is_vector_arith_imm_pattern(n, m)) {
(UseSVE > 0 && m->Opcode() == Op_VectorStoreMask && n->Opcode() == Op_StoreVector) ||
is_vector_arith_imm_pattern(n, m)) {
mstack.push(m, Visit); mstack.push(m, Visit);
return true; return true;
} }

View file

@ -148,7 +148,7 @@ LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
if (index->is_constant()) { if (index->is_constant()) {
LIR_Const *constant = index->as_constant_ptr(); LIR_Const *constant = index->as_constant_ptr();
if (constant->type() == T_INT) { if (constant->type() == T_INT) {
large_disp += index->as_jint() << shift; large_disp += ((intx)index->as_jint()) << shift;
} else { } else {
assert(constant->type() == T_LONG, "should be"); assert(constant->type() == T_LONG, "should be");
jlong c = index->as_jlong() << shift; 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()) { if (large_disp == 0 && index->is_register()) {
return new LIR_Address(base, index, type); return new LIR_Address(base, index, type);
} else { } 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); 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 offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
int elem_size = type2aelembytes(type); int elem_size = type2aelembytes(type);
int shift = exact_log2(elem_size); int shift = exact_log2(elem_size);
return generate_address(array_opr, index_opr, shift, offset_in_bytes, type);
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;
} }
LIR_Opr LIRGenerator::load_immediate(int x, BasicType 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. * Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
@ -29,6 +29,7 @@
#include "jvm.h" #include "jvm.h"
#include "asm/assembler.hpp" #include "asm/assembler.hpp"
#include "asm/assembler.inline.hpp" #include "asm/assembler.inline.hpp"
#include "ci/ciEnv.hpp"
#include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/cardTableBarrierSet.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); Instruction_aarch64::patch(branch+8, 20, 5, (dest >>= 16) & 0xffff);
assert(target_addr_for_insn(branch) == target, "should be"); assert(target_addr_for_insn(branch) == target, "should be");
instructions = 3; instructions = 3;
} else if (Instruction_aarch64::extract(insn, 31, 22) == 0b1011100101 && } else if (NativeInstruction::is_ldrw_to_zr(address(&insn))) {
Instruction_aarch64::extract(insn, 4, 0) == 0b11111) {
// nothing to do // nothing to do
assert(target == 0, "did not expect to relocate target for polling page load"); assert(target == 0, "did not expect to relocate target for polling page load");
} else { } 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)) 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[1], 20, 5)) << 16)
+ (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32)); + (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 { } else {
ShouldNotReachHere(); ShouldNotReachHere();
} }
return address(((uint64_t)insn_addr + (offset << 2))); 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) { void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod) {
if (acquire) { if (acquire) {
lea(rscratch1, Address(rthread, JavaThread::polling_word_offset())); lea(rscratch1, Address(rthread, JavaThread::polling_word_offset()));

View file

@ -600,10 +600,15 @@ public:
static bool uses_implicit_null_check(void* address); 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(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) { static address target_addr_for_insn(address insn_addr) {
unsigned insn = *(unsigned*)insn_addr; unsigned insn = *(unsigned*)insn_addr;
return target_addr_for_insn(insn_addr, insn); 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. // Required platform-specific helpers for Label::patch_instructions.
// They _shadow_ the declarations in AbstractAssembler, which are undefined. // 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. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
@ -315,7 +315,7 @@ void NativeMovRegMem::set_offset(int x) {
void NativeMovRegMem::verify() { void NativeMovRegMem::verify() {
#ifdef ASSERT #ifdef ASSERT
address dest = MacroAssembler::target_addr_for_insn(instruction_address()); address dest = MacroAssembler::target_addr_for_insn_or_null(instruction_address());
#endif #endif
} }
@ -329,7 +329,7 @@ void NativeJump::check_verified_entry_alignment(address entry, address verified_
address NativeJump::jump_destination() const { 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 // We use jump to self as the unresolved address which the inline
// cache code (and relocs) know about // 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) { if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false; 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; return false;
} }
// These are hacks to keep us out of trouble. // 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) { if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
return false; 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; return false;
} }
// These are hacks to keep us out of trouble. // 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; LIR_Address* addr;
if (index_opr->is_constant()) { if (index_opr->is_constant()) {
int elem_size = type2aelembytes(type); int elem_size = type2aelembytes(type);
addr = new LIR_Address(array_opr, #ifdef _LP64
offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type); 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 { } else {
#ifdef _LP64 #ifdef _LP64
if (index_opr->type() == T_INT) { 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) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019 SAP SE. All rights reserved. * Copyright (c) 2012, 2022 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 we were running Java code when SIGPROF came in.
if (isInJava) { if (isInJava) {
ucontext_t* uc = (ucontext_t*) ucontext; ucontext_t* uc = (ucontext_t*) ucontext;
frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], address pc = (address)uc->uc_mcontext.regs->nip;
(address)uc->uc_mcontext.regs->nip);
if (ret_frame.pc() == NULL) { if (pc == NULL) {
// ucontext wasn't useful // ucontext wasn't useful
return false; return false;
} }
frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], pc);
if (ret_frame.fp() == NULL) { if (ret_frame.fp() == NULL) {
// The found frame does not have a valid frame pointer. // The found frame does not have a valid frame pointer.
// Bail out because this will create big trouble later on, either // 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); cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
if (cha_monomorphic_target != NULL) { if (cha_monomorphic_target != NULL) {
if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) { if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
// If CHA is able to bind this invoke then update the class ciInstanceKlass* holder = cha_monomorphic_target->holder();
// to match that class, otherwise klass will refer to the ciInstanceKlass* constraint = (holder->is_subtype_of(singleton) ? holder : singleton); // avoid upcasts
// interface.
klass = cha_monomorphic_target->holder();
actual_recv = declared_interface; actual_recv = declared_interface;
// insert a check it's really the expected class. // 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_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 // pass the result of the checkcast so that the compiler has
// more accurate type info in the inlinee // more accurate type info in the inlinee
better_receiver = append_split(c); better_receiver = append_split(c);
dependency_recorder()->assert_unique_implementor(declared_interface, singleton);
} else { } else {
cha_monomorphic_target = NULL; // subtype check against Object is useless 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) { 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 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); int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);
while (fast != -1 && fast != 0) { while (fast != -1 && fast != 0) {
if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) { if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) {
return true; // found a circularity 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; for (int y = idx + InstanceKlass::inner_class_next_offset; y < length;
y += InstanceKlass::inner_class_next_offset) { y += InstanceKlass::inner_class_next_offset) {
// To maintain compatibility, throw an exception if duplicate inner classes // 4347400: make sure there's no duplicate entry in the classes array
// entries are found. if (_major_version >= JAVA_1_5_VERSION) {
guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) || guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) ||
_inner_classes->at(idx+1) != _inner_classes->at(y+1) || _inner_classes->at(idx+1) != _inner_classes->at(y+1) ||
_inner_classes->at(idx+2) != _inner_classes->at(y+2) || _inner_classes->at(idx+2) != _inner_classes->at(y+2) ||
_inner_classes->at(idx+3) != _inner_classes->at(y+3)), _inner_classes->at(idx+3) != _inner_classes->at(y+3)),
"Duplicate entry in InnerClasses attribute in class file %s", "Duplicate entry in InnerClasses attribute in class file %s",
CHECK_(true)); CHECK_(true));
}
// Return true if there are two entries with the same inner_class_info_index. // Return true if there are two entries with the same inner_class_info_index.
if (_inner_classes->at(y) == _inner_classes->at(idx)) { if (_inner_classes->at(y) == _inner_classes->at(idx)) {
return true; 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()); inner_classes->at_put(index++, inner_access_flags.as_short());
} }
// 4347400: make sure there's no duplicate entry in the classes array // Check for circular and duplicate entries.
// Also, check for circular entries.
bool has_circularity = false; 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); has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0);
if (has_circularity) { if (has_circularity) {
// If circularity check failed then ignore InnerClasses attribute. // 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 // 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); buffer = NEW_RESOURCE_ARRAY(u1, size);
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL; if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
// return result // return result
if (nul_terminate) { if (nul_terminate) {
buffer[*filesize] = 0; buffer[size - 1] = 0;
} }
return buffer; 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) { void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) {
check_ctxk(ctxk); check_ctxk(ctxk);
assert_common_1(no_finalizable_subclasses, 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); 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) { void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
check_ctxk(ctxk); check_ctxk(ctxk);
check_unique_method(ctxk, uniqm); check_unique_method(ctxk, uniqm);
@ -580,6 +593,7 @@ const char* Dependencies::_dep_name[TYPE_LIMIT] = {
"abstract_with_unique_concrete_subtype", "abstract_with_unique_concrete_subtype",
"unique_concrete_method_2", "unique_concrete_method_2",
"unique_concrete_method_4", "unique_concrete_method_4",
"unique_implementor",
"no_finalizable_subclasses", "no_finalizable_subclasses",
"call_site_target_value" "call_site_target_value"
}; };
@ -591,6 +605,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = {
2, // abstract_with_unique_concrete_subtype ctxk, k 2, // abstract_with_unique_concrete_subtype ctxk, k
2, // unique_concrete_method_2 ctxk, m 2, // unique_concrete_method_2 ctxk, m
4, // unique_concrete_method_4 ctxk, m, resolved_klass, resolved_method 4, // unique_concrete_method_4 ctxk, m, resolved_klass, resolved_method
2, // unique_implementor ctxk, implementor
1, // no_finalizable_subclasses ctxk 1, // no_finalizable_subclasses ctxk
2 // call_site_target_value call_site, method_handle 2 // call_site_target_value call_site, method_handle
}; };
@ -1813,6 +1828,16 @@ Klass* Dependencies::check_unique_concrete_method(InstanceKlass* ctxk,
return NULL; 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. // Search for AME.
// There are two version of checks. // There are two version of checks.
// 1) Spot checking version(Classload time). Newly added class is checked for AME. // 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: case unique_concrete_method_4:
witness = check_unique_concrete_method(context_type(), method_argument(1), type_argument(2), method_argument(3), changes); witness = check_unique_concrete_method(context_type(), method_argument(1), type_argument(2), method_argument(3), changes);
break; break;
case unique_implementor:
witness = check_unique_implementor(context_type(), type_argument(1), changes);
break;
case no_finalizable_subclasses: case no_finalizable_subclasses:
witness = check_has_no_finalizable_subclasses(context_type(), changes); witness = check_has_no_finalizable_subclasses(context_type(), changes);
break; break;

View file

@ -143,6 +143,9 @@ class Dependencies: public ResourceObj {
// of the analysis. // of the analysis.
unique_concrete_method_4, // one unique concrete method under CX 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 // This dependency asserts that no instances of class or it's
// subclasses require finalization registration. // subclasses require finalization registration.
no_finalizable_subclasses, no_finalizable_subclasses,
@ -329,7 +332,10 @@ class Dependencies: public ResourceObj {
assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract"); assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract");
} }
static void check_unique_method(ciKlass* ctxk, ciMethod* m) { 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); 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_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);
void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm, ciKlass* resolved_klass, ciMethod* resolved_method); 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_has_no_finalizable_subclasses(ciKlass* ctxk);
void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
#if INCLUDE_JVMCI #if INCLUDE_JVMCI
private: private:
static void check_ctxk(Klass* ctxk) { static void check_ctxk(Klass* ctxk) {
@ -366,6 +372,7 @@ class Dependencies: public ResourceObj {
void assert_evol_method(Method* m); void assert_evol_method(Method* m);
void assert_has_no_finalizable_subclasses(Klass* ctxk); void assert_has_no_finalizable_subclasses(Klass* ctxk);
void assert_leaf_type(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_unique_concrete_method(Klass* ctxk, Method* uniqm);
void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck); void assert_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck);
void assert_call_site_target_value(oop callSite, oop methodHandle); 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_evol_method(Method* m);
static Klass* check_leaf_type(InstanceKlass* ctxk); 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_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, 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_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); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 // Increment _num_cards before adding to queue, so queue removal doesn't
// need to deal with _num_cards possibly going negative. // need to deal with _num_cards possibly going negative.
size_t new_num_cards = Atomic::add(&_num_cards, buffer_size() - cbn->index()); 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); _completed.push(*cbn);
}
if ((new_num_cards > process_cards_threshold()) && if ((new_num_cards > process_cards_threshold()) &&
(_primary_refinement_thread != NULL)) { (_primary_refinement_thread != NULL)) {
_primary_refinement_thread->activate(); _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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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) { inline traceid JfrTraceIdLoadBarrier::load(const ClassLoaderData* cld) {
assert(cld != NULL, "invariant"); 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) { 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 { } else {
it->push(&_default_vtable_indices); 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) { if (itable_length() > 0) {
itableOffsetEntry* ioe = (itableOffsetEntry*)start_of_itable(); 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, CallGenerator* miss_cg = CallGenerator::for_uncommon_trap(callee,
Deoptimization::Reason_class_check, Deoptimization::Action_none); 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) { 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); dependencies()->assert_unique_concrete_method(declared_interface, cha_monomorphic_target, declared_interface, callee);
return cg; return cg;
} }

View file

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

View file

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

View file

@ -1315,6 +1315,8 @@ public class ObjectInputStream
* <li>each object reference previously deserialized from the stream * <li>each object reference previously deserialized from the stream
* (class is {@code null}, arrayLength is -1), * (class is {@code null}, arrayLength is -1),
* <li>each regular class (class is not {@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 * <li>each interface of a dynamic proxy and the dynamic proxy class itself
* (class is not {@code null}, arrayLength is -1), * (class is not {@code null}, arrayLength is -1),
* <li>each array is filtered using the array type and length of the array * <li>each array is filtered using the array type and length of the array
@ -2071,6 +2073,30 @@ public class ObjectInputStream
totalObjectRefs++; totalObjectRefs++;
depth++; depth++;
desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); 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 { } finally {
depth--; depth--;
} }
@ -2529,6 +2555,13 @@ public class ObjectInputStream
throw new InternalError(); throw new InternalError();
} }
clear(); 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); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,7 +26,12 @@
package java.lang; package java.lang;
import java.io.IOException; 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; import jdk.internal.vm.annotation.IntrinsicCandidate;
/** /**
@ -106,7 +111,7 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
*/ */
public final class StringBuffer public final class StringBuffer
extends AbstractStringBuilder 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; private transient String toStringCache;
/** use serialVersionUID from JDK 1.0.2 for interoperability */ /** use serialVersionUID from JDK 1.0.2 for interoperability */
@java.io.Serial @Serial
static final long serialVersionUID = 3388685877147921107L; static final long serialVersionUID = 3388685877147921107L;
/** /**
@ -725,25 +730,25 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
* A flag indicating whether the backing array is shared. * A flag indicating whether the backing array is shared.
* The value is ignored upon deserialization. * The value is ignored upon deserialization.
*/ */
@java.io.Serial @Serial
private static final java.io.ObjectStreamField[] serialPersistentFields = private static final ObjectStreamField[] serialPersistentFields =
{ {
new java.io.ObjectStreamField("value", char[].class), new ObjectStreamField("value", char[].class),
new java.io.ObjectStreamField("count", Integer.TYPE), new ObjectStreamField("count", Integer.TYPE),
new java.io.ObjectStreamField("shared", Boolean.TYPE), new ObjectStreamField("shared", Boolean.TYPE),
}; };
/** /**
* The {@code writeObject} method is called to write the state of the {@code StringBuffer} to * The {@code writeObject} method is called to write the state of the
* a stream. * {@code StringBuffer} to a stream.
* *
* @param s the {@code ObjectOutputStream} to which data is written * @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
*/ */
@java.io.Serial @Serial
private synchronized void writeObject(java.io.ObjectOutputStream s) private synchronized void writeObject(ObjectOutputStream s)
throws java.io.IOException { throws IOException {
java.io.ObjectOutputStream.PutField fields = s.putFields(); ObjectOutputStream.PutField fields = s.putFields();
char[] val = new char[capacity()]; char[] val = new char[capacity()];
if (isLatin1()) { if (isLatin1()) {
StringLatin1.getChars(value, 0, count, val, 0); 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 * The {@code readObject} method is called to restore the state of the
* a stream. * {@code StringBuffer} from a stream.
* *
* @param s the {@code ObjectInputStream} from which data is read * @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded * @throws ClassNotFoundException if a serialized class cannot be loaded
*/ */
@java.io.Serial @Serial
private void readObject(java.io.ObjectInputStream s) private void readObject(ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
java.io.ObjectInputStream.GetField fields = s.readFields(); ObjectInputStream.GetField fields = s.readFields();
char[] val = (char[])fields.get("value", null); 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); initBytes(val, 0, val.length);
count = fields.get("count", 0); count = c;
// ignore shared field
} }
synchronized void getBytes(byte[] dst, int dstBegin, byte coder) { 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 jdk.internal.vm.annotation.IntrinsicCandidate;
import java.io.IOException; 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 * A mutable sequence of characters. This class provides an API compatible
@ -90,7 +94,7 @@ public final class StringBuilder
{ {
/** use serialVersionUID for interoperability */ /** use serialVersionUID for interoperability */
@java.io.Serial @Serial
static final long serialVersionUID = 4383685877147921099L; static final long serialVersionUID = 4383685877147921099L;
/** /**
@ -464,9 +468,8 @@ public final class StringBuilder
* @param s the {@code ObjectOutputStream} to which data is written * @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
*/ */
@java.io.Serial @Serial
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(ObjectOutputStream s) throws IOException {
throws java.io.IOException {
s.defaultWriteObject(); s.defaultWriteObject();
s.writeInt(count); s.writeInt(count);
char[] val = new char[capacity()]; char[] val = new char[capacity()];
@ -486,13 +489,16 @@ public final class StringBuilder
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded * @throws ClassNotFoundException if a serialized class cannot be loaded
*/ */
@java.io.Serial @Serial
private void readObject(java.io.ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); s.defaultReadObject();
count = s.readInt(); int c = s.readInt();
char[] val = (char[]) s.readObject(); char[] val = (char[]) s.readObject();
initBytes(val, 0, val.length); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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). * Reconstitute the Hashtable from a stream (i.e., deserialize it).
*/ */
@java.io.Serial @java.io.Serial
private void readObject(java.io.ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
readHashtable(s); readHashtable(s);
} }
@ -1263,14 +1263,16 @@ public class Hashtable<K,V>
* Perform deserialization of the Hashtable from an ObjectInputStream. * Perform deserialization of the Hashtable from an ObjectInputStream.
* The Properties class overrides this method. * The Properties class overrides this method.
*/ */
void readHashtable(java.io.ObjectInputStream s) void readHashtable(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
// Read in the threshold and loadFactor
s.defaultReadObject();
// Validate loadFactor (ignore threshold - it will be re-computed) ObjectInputStream.GetField fields = s.readFields();
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new StreamCorruptedException("Illegal Load: " + loadFactor); // 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 // Read the original length of the array and number of elements
int origlength = s.readInt(); int origlength = s.readInt();
@ -1282,13 +1284,13 @@ public class Hashtable<K,V>
// Clamp original length to be more than elements / loadFactor // Clamp original length to be more than elements / loadFactor
// (this is the invariant enforced with auto-growth) // (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 // Compute new length with a bit of room 5% + 3 to grow but
// no larger than the clamped original length. Make the length // no larger than the clamped original length. Make the length
// odd if it's large enough, this helps distribute the entries. // odd if it's large enough, this helps distribute the entries.
// Guard against the length ending up zero, that's not valid. // 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) if (length > elements && (length & 1) == 0)
length--; length--;
length = Math.min(length, origlength); 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 // Check Map.Entry[].class since it's the nearest public type to
// what we're actually creating. // what we're actually creating.
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length); SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length);
Hashtable.UnsafeHolder.putLoadFactor(this, lf);
table = new Entry<?,?>[length]; 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; count = 0;
// Read the number of elements and then all the key/value objects // 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 * The put method used by readObject. This is provided because put
* is overridable and should not be called in readObject since the * 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,8 @@
package java.util; package java.util;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@ -1267,12 +1269,12 @@ public class IdentityHashMap<K,V>
* particular order. * particular order.
*/ */
@java.io.Serial @java.io.Serial
private void writeObject(java.io.ObjectOutputStream s) private void writeObject(ObjectOutputStream s)
throws java.io.IOException { throws java.io.IOException {
// Write out and any hidden stuff // Write out size (number of mappings) and any hidden stuff
s.defaultWriteObject(); s.defaultWriteObject();
// Write out size (number of Mappings) // Write out size again (maintained for backward compatibility)
s.writeInt(size); s.writeInt(size);
// Write out keys and values (alternating) // Write out keys and values (alternating)
@ -1291,18 +1293,20 @@ public class IdentityHashMap<K,V>
* deserializes it). * deserializes it).
*/ */
@java.io.Serial @java.io.Serial
private void readObject(java.io.ObjectInputStream s) private void readObject(ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException { throws java.io.IOException, ClassNotFoundException {
// Read in any hidden stuff // Size (number of mappings) is written to the stream twice
s.defaultReadObject(); // 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(); int size = s.readInt();
if (size < 0) if (size < 0)
throw new java.io.StreamCorruptedException throw new java.io.StreamCorruptedException
("Illegal mappings count: " + size); ("Illegal mappings count: " + size);
int cap = capacity(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); init(cap);
// Read the keys and values, and put the mappings in the table // 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package java.util.jar; package java.util.jar;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; 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 { int read(Manifest.FastInputStream is, byte[] lbuf, String filename, int lineNumber) throws IOException {
String name = null, value; String name = null, value;
byte[] lastline = null; ByteArrayOutputStream fullLine = new ByteArrayOutputStream();
int len; int len;
while ((len = is.readLine(lbuf)) != -1) { while ((len = is.readLine(lbuf)) != -1) {
@ -392,15 +393,12 @@ public class Attributes implements Map<Object,Object>, Cloneable {
+ Manifest.getErrorPosition(filename, lineNumber) + ")"); + Manifest.getErrorPosition(filename, lineNumber) + ")");
} }
lineContinued = true; lineContinued = true;
byte[] buf = new byte[lastline.length + len - 1]; fullLine.write(lbuf, 1, len - 1);
System.arraycopy(lastline, 0, buf, 0, lastline.length);
System.arraycopy(lbuf, 1, buf, lastline.length, len - 1);
if (is.peek() == ' ') { if (is.peek() == ' ') {
lastline = buf;
continue; continue;
} }
value = new String(buf, 0, buf.length, UTF_8.INSTANCE); value = fullLine.toString(UTF_8.INSTANCE);
lastline = null; fullLine.reset();
} else { } else {
while (lbuf[i++] != ':') { while (lbuf[i++] != ':') {
if (i >= len) { 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); name = new String(lbuf, 0, i - 2, UTF_8.INSTANCE);
if (is.peek() == ' ') { if (is.peek() == ' ') {
lastline = new byte[len - i]; fullLine.reset();
System.arraycopy(lbuf, i, lastline, 0, len - i); fullLine.write(lbuf, i, len - i);
continue; continue;
} }
value = new String(lbuf, i, len - i, UTF_8.INSTANCE); 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, private static final int countChars(CharSequence seq, int index,
int lengthInCodePoints) { int lengthInCodePoints) {
// optimization // optimization
if (lengthInCodePoints == 1 && !Character.isHighSurrogate(seq.charAt(index))) { if (lengthInCodePoints == 1 && index >= 0 && index < seq.length() &&
assert (index >= 0 && index < seq.length()); !Character.isHighSurrogate(seq.charAt(index))) {
return 1; return 1;
} }
int length = seq.length(); int length = seq.length();

View file

@ -77,15 +77,18 @@ public class EncryptedPrivateKeyInfo {
* @exception NullPointerException if the <code>encoded</code> is null. * @exception NullPointerException if the <code>encoded</code> is null.
* @exception IOException if error occurs when parsing the ASN.1 encoding. * @exception IOException if error occurs when parsing the ASN.1 encoding.
*/ */
public EncryptedPrivateKeyInfo(byte[] encoded) public EncryptedPrivateKeyInfo(byte[] encoded) throws IOException {
throws IOException {
if (encoded == null) { if (encoded == null) {
throw new NullPointerException("the encoded parameter " + throw new NullPointerException("the encoded parameter " +
"must be non-null"); "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]; DerValue[] seq = new DerValue[2];
seq[0] = val.data.getDerValue(); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -127,7 +127,9 @@ public class ContentInfo {
if (oldStyle) { if (oldStyle) {
// JDK1.1.x-style encoding // JDK1.1.x-style encoding
if (typeAndContent.length > 1) { // content is OPTIONAL
content = typeAndContent[1]; content = typeAndContent[1];
}
} else { } else {
// This is the correct, standards-compliant encoding. // This is the correct, standards-compliant encoding.
// Parse the content (OPTIONAL field). // Parse the content (OPTIONAL field).

View file

@ -383,8 +383,15 @@ public class SignerInfo implements DerEncoder {
if (digestAlgName.equals("SHAKE256") if (digestAlgName.equals("SHAKE256")
|| digestAlgName.equals("SHAKE256-LEN")) { || digestAlgName.equals("SHAKE256-LEN")) {
if (digestAlgName.equals("SHAKE256-LEN")) { if (digestAlgName.equals("SHAKE256-LEN")) {
int v = new DerValue(digestAlgorithmId // RFC8419: for EdDSA in CMS, the id-shake256-len
.getEncodedParams()).getInteger(); // 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) { if (v != 512) {
throw new SignatureException( throw new SignatureException(
"Unsupported id-shake256-" + v); "Unsupported id-shake256-" + v);
@ -527,6 +534,7 @@ public class SignerInfo implements DerEncoder {
if (spec == null) { if (spec == null) {
throw new NoSuchAlgorithmException("Missing PSSParameterSpec for RSASSA-PSS algorithm"); throw new NoSuchAlgorithmException("Missing PSSParameterSpec for RSASSA-PSS algorithm");
} }
if (!AlgorithmId.get(spec.getDigestAlgorithm()).equals(digAlgId)) { if (!AlgorithmId.get(spec.getDigestAlgorithm()).equals(digAlgId)) {
throw new NoSuchAlgorithmException("Incompatible digest algorithm"); 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)) { if (!val.getOID().equals(AlgorithmId.MGF1_oid)) {
throw new IOException("Only MGF1 mgf is supported"); 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( AlgorithmId params = AlgorithmId.parse(
new DerValue(val.getEncodedParams())); new DerValue(encodedParams));
String mgfDigestName = params.getName(); String mgfDigestName = params.getName();
switch (mgfDigestName) { switch (mgfDigestName) {
case "SHA-1": 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.UnixDomainSocketAddress;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions; import java.net.StandardSocketOptions;
import java.nio.*; import java.nio.*;
import java.nio.channels.*; import java.nio.channels.*;
@ -164,10 +162,6 @@ class PipeImpl
try { try {
if (ssc != null) if (ssc != null)
ssc.close(); ssc.close();
if (sa instanceof UnixDomainSocketAddress) {
Path path = ((UnixDomainSocketAddress) sa).getPath();
Files.deleteIfExists(path);
}
} catch (IOException e2) {} } catch (IOException e2) {}
} }
} }
@ -184,8 +178,7 @@ class PipeImpl
/** /**
* Creates Pipe implementation that supports optionally buffering. * Creates Pipe implementation that supports optionally buffering.
* *
* @implNote The pipe uses Unix domain sockets where possible. It uses a * @implNote Uses a loopback connection. When buffering is
* loopback connection on older editions of Windows. When buffering is
* disabled then it sets TCP_NODELAY on the sink channel. * disabled then it sets TCP_NODELAY on the sink channel.
*/ */
@SuppressWarnings("removal") @SuppressWarnings("removal")
@ -212,23 +205,8 @@ class PipeImpl
return sink; return sink;
} }
private static volatile boolean noUnixDomainSockets;
private static ServerSocketChannel createListener() throws IOException { private static ServerSocketChannel createListener() throws IOException {
ServerSocketChannel listener = null; ServerSocketChannel listener = ServerSocketChannel.open();
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();
InetAddress lb = InetAddress.getLoopbackAddress(); InetAddress lb = InetAddress.getLoopbackAddress();
listener.bind(new InetSocketAddress(lb, 0)); listener.bind(new InetSocketAddress(lb, 0));
return listener; return listener;

View file

@ -52,6 +52,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import javax.imageio.IIOException; import javax.imageio.IIOException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam; 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. * Process the image header.
* *
@ -305,8 +333,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
// Read in the palette // Read in the palette
int numberOfEntries = (int)((bitmapOffset - 14 - size) / 3); int numberOfEntries = (int)((bitmapOffset - 14 - size) / 3);
int sizeOfPalette = numberOfEntries*3; int sizeOfPalette = numberOfEntries*3;
palette = new byte[sizeOfPalette]; readColorPalette(sizeOfPalette);
iis.readFully(palette, 0, sizeOfPalette);
metadata.palette = palette; metadata.palette = palette;
metadata.paletteSize = numberOfEntries; metadata.paletteSize = numberOfEntries;
} else { } else {
@ -343,8 +370,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
} }
int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries * 4; int sizeOfPalette = numberOfEntries * 4;
palette = new byte[sizeOfPalette]; readColorPalette(sizeOfPalette);
iis.readFully(palette, 0, sizeOfPalette);
metadata.palette = palette; metadata.palette = palette;
metadata.paletteSize = numberOfEntries; metadata.paletteSize = numberOfEntries;
@ -404,8 +430,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
if (colorsUsed != 0) { if (colorsUsed != 0) {
// there is a palette // there is a palette
sizeOfPalette = (int)colorsUsed*4; sizeOfPalette = (int)colorsUsed*4;
palette = new byte[sizeOfPalette]; readColorPalette(sizeOfPalette);
iis.readFully(palette, 0, sizeOfPalette);
metadata.palette = palette; metadata.palette = palette;
metadata.paletteSize = (int)colorsUsed; metadata.paletteSize = (int)colorsUsed;
@ -430,8 +455,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
// Read in the palette // Read in the palette
int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries*4; int sizeOfPalette = numberOfEntries*4;
palette = new byte[sizeOfPalette]; readColorPalette(sizeOfPalette);
iis.readFully(palette, 0, sizeOfPalette);
metadata.palette = palette; metadata.palette = palette;
metadata.paletteSize = numberOfEntries; metadata.paletteSize = numberOfEntries;
@ -529,8 +553,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
// Read in the palette // Read in the palette
int numberOfEntries = (int)((bitmapOffset-14-size) / 4); int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
int sizeOfPalette = numberOfEntries*4; int sizeOfPalette = numberOfEntries*4;
palette = new byte[sizeOfPalette]; readColorPalette(sizeOfPalette);
iis.readFully(palette, 0, sizeOfPalette);
metadata.palette = palette; metadata.palette = palette;
metadata.paletteSize = numberOfEntries; metadata.paletteSize = numberOfEntries;
@ -592,7 +615,7 @@ public class BMPImageReader extends ImageReader implements BMPConstants {
} }
if (metadata.compression == BI_RGB) { if (metadata.compression == BI_RGB) {
long imageDataSize = (width * height * (bitsPerPixel / 8)); long imageDataSize = ((long)width * height * (bitsPerPixel / 8));
if (imageDataSize > (bitmapFileSize - bitmapOffset)) { if (imageDataSize > (bitmapFileSize - bitmapOffset)) {
throw new IIOException(I18N.getString("BMPImageReader9")); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageInputStream;
/** /**
@ -213,4 +215,47 @@ public class ReaderUtil {
} }
return result; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 ti = tableIndex;
int oc = oldCode; int oc = oldCode;

View file

@ -1156,6 +1156,13 @@ public class JPEGImageReader extends ImageReader {
throw new IIOException("Unsupported Image Type"); 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); image = getDestination(param, imageTypes, width, height);
imRas = image.getRaster(); imRas = image.getRaster();

View file

@ -1415,6 +1415,13 @@ public class PNGImageReader extends ImageReader {
int width = metadata.IHDR_width; int width = metadata.IHDR_width;
int height = metadata.IHDR_height; 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 // Init default values
sourceXSubsampling = 1; sourceXSubsampling = 1;
sourceYSubsampling = 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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. * @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; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.IIOException;
import javax.imageio.plugins.tiff.BaselineTIFFTagSet; import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
import javax.imageio.plugins.tiff.TIFFField; import javax.imageio.plugins.tiff.TIFFField;
import com.sun.imageio.plugins.common.ReaderUtil;
class TIFFFaxDecompressor extends TIFFDecompressor { class TIFFFaxDecompressor extends TIFFDecompressor {
@ -637,14 +638,14 @@ class TIFFFaxDecompressor extends TIFFDecompressor {
this.bitsPerScanline = scanlineStride*8; this.bitsPerScanline = scanlineStride*8;
this.lineBitNum = 8*dstOffset; this.lineBitNum = 8*dstOffset;
this.data = new byte[byteCount];
this.bitPointer = 0; this.bitPointer = 0;
this.bytePointer = 0; this.bytePointer = 0;
this.prevChangingElems = new int[w + 1]; this.prevChangingElems = new int[w + 1];
this.currChangingElems = new int[w + 1]; this.currChangingElems = new int[w + 1];
stream.seek(offset); stream.seek(offset);
stream.readFully(data); this.data = ReaderUtil.
staggeredReadByteStream(stream, byteCount);
if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) { if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE) {
decodeRLE(); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 java.io.IOException;
import javax.imageio.IIOException; import javax.imageio.IIOException;
import javax.imageio.plugins.tiff.BaselineTIFFTagSet; import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
import com.sun.imageio.plugins.common.ReaderUtil;
class TIFFLZWDecompressor extends TIFFDecompressor { class TIFFLZWDecompressor extends TIFFDecompressor {
@ -95,9 +96,8 @@ class TIFFLZWDecompressor extends TIFFDecompressor {
} }
stream.seek(offset); stream.seek(offset);
byte[] sdata = ReaderUtil.
byte[] sdata = new byte[byteCount]; staggeredReadByteStream(stream, byteCount);
stream.readFully(sdata);
if (flipBits) { if (flipBits) {
for (int i = 0; i < byteCount; i++) { for (int i = 0; i < byteCount; i++) {

View file

@ -136,12 +136,7 @@ public class TIFFNullDecompressor extends TIFFDecompressor {
int lastRow = activeSrcHeight - 1; int lastRow = activeSrcHeight - 1;
for (int y = 0; y < activeSrcHeight; y++) { for (int y = 0; y < activeSrcHeight; y++) {
int bytesRead = stream.read(b, dstOffset, activeBytesPerRow); stream.readFully(b, dstOffset, activeBytesPerRow);
if (bytesRead < 0) {
throw new EOFException();
} else if (bytesRead != activeBytesPerRow) {
break;
}
dstOffset += scanlineStride; dstOffset += scanlineStride;
// Skip unneeded bytes (row suffix + row prefix). // Skip unneeded bytes (row suffix + row prefix).
@ -154,17 +149,10 @@ public class TIFFNullDecompressor extends TIFFDecompressor {
stream.seek(offset); stream.seek(offset);
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8; int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
if(bytesPerRow == scanlineStride) { if(bytesPerRow == scanlineStride) {
if (stream.read(b, dstOffset, bytesPerRow*srcHeight) < 0) { stream.readFully(b, dstOffset, bytesPerRow*srcHeight);
throw new EOFException();
}
} else { } else {
for (int y = 0; y < srcHeight; y++) { for (int y = 0; y < srcHeight; y++) {
int bytesRead = stream.read(b, dstOffset, bytesPerRow); stream.readFully(b, dstOffset, bytesPerRow);
if (bytesRead < 0) {
throw new EOFException();
} else if (bytesRead != bytesPerRow) {
break;
}
dstOffset += scanlineStride; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,6 +25,7 @@
package com.sun.imageio.plugins.tiff; package com.sun.imageio.plugins.tiff;
import java.io.IOException; import java.io.IOException;
import com.sun.imageio.plugins.common.ReaderUtil;
public class TIFFPackBitsDecompressor extends TIFFDecompressor { public class TIFFPackBitsDecompressor extends TIFFDecompressor {
@ -77,8 +78,8 @@ public class TIFFPackBitsDecompressor extends TIFFDecompressor {
int scanlineStride) throws IOException { int scanlineStride) throws IOException {
stream.seek(offset); stream.seek(offset);
byte[] srcData = new byte[byteCount]; byte[] srcData = ReaderUtil.
stream.readFully(srcData); staggeredReadByteStream(stream, byteCount);
int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8; int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
byte[] buf; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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); super.setOffset(offset);
} }
public void setByteCount(int byteCount) { public void setByteCount(int byteCount) throws IOException {
if(decompressor != null) { if(decompressor != null) {
decompressor.setByteCount(byteCount); decompressor.setByteCount(byteCount);
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -54,7 +54,7 @@ import org.w3c.dom.Document;
* @author Morten Jorgensen * @author Morten Jorgensen
* @author G. Todd Miller * @author G. Todd Miller
* @author John Howard, JohnH@schemasoft.com * @author John Howard, JohnH@schemasoft.com
* @LastModified: May 2021 * @LastModified: Sept 2021
*/ */
public abstract class AbstractTranslet implements Translet { public abstract class AbstractTranslet implements Translet {
@ -116,6 +116,9 @@ public abstract class AbstractTranslet implements Translet {
*/ */
private String _accessExternalStylesheet = JdkConstants.EXTERNAL_ACCESS_DEFAULT; private String _accessExternalStylesheet = JdkConstants.EXTERNAL_ACCESS_DEFAULT;
// The error message when access to exteranl resources is rejected
private String _accessErr = null;
/************************************************************************ /************************************************************************
* Debugging * Debugging
************************************************************************/ ************************************************************************/
@ -786,6 +789,20 @@ public abstract class AbstractTranslet implements Translet {
_accessExternalStylesheet = protocols; _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 * DOMImplementation caching for basis library
************************************************************************/ ************************************************************************/

View file

@ -101,7 +101,7 @@ import org.xml.sax.ext.LexicalHandler;
* @author Morten Jorgensen * @author Morten Jorgensen
* @author G. Todd Miller * @author G. Todd Miller
* @author Santiago Pericas-Geertsen * @author Santiago Pericas-Geertsen
* @LastModified: June 2021 * @LastModified: Sept 2021
*/ */
public final class TransformerImpl extends Transformer public final class TransformerImpl extends Transformer
implements DOMCache implements DOMCache
@ -1351,8 +1351,33 @@ public final class TransformerImpl extends Transformer
} }
if (resolvedSource == null) { 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) ; 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 * 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 Andy Clark, IBM
* @author Arnaud Le Hors, IBM * @author Arnaud Le Hors, IBM
* @author Eric Ye, IBM * @author Eric Ye, IBM
* * @LastModified: Aug 2021
*/ */
public class XML11DocumentScannerImpl public class XML11DocumentScannerImpl
extends XMLDocumentScannerImpl { extends XMLDocumentScannerImpl {
@ -278,16 +278,6 @@ public class XML11DocumentScannerImpl
+ fStringBuffer.toString() + "\""); + 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)) { else if (c != -1 && XMLChar.isHighSurrogate(c)) {
fStringBuffer3.clear(); fStringBuffer3.clear();
if (scanSurrogates(fStringBuffer3)) { if (scanSurrogates(fStringBuffer3)) {

View file

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

View file

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

View file

@ -21,6 +21,8 @@
package com.sun.org.apache.xerces.internal.impl; 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.XMLScanner.NameType;
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
@ -55,7 +57,7 @@ import java.util.Locale;
* @author Arnaud Le Hors, IBM * @author Arnaud Le Hors, IBM
* @author K.Venugopal Sun Microsystems * @author K.Venugopal Sun Microsystems
* *
* @LastModified: Apr 2021 * @LastModified: Sep 2021
*/ */
public class XMLEntityScanner implements XMLLocator { public class XMLEntityScanner implements XMLLocator {
@ -149,6 +151,15 @@ public class XMLEntityScanner implements XMLLocator {
// indicates that the operation is for detecting XML version // indicates that the operation is for detecting XML version
boolean detectingVersion = false; 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 // Constructors
// //
@ -553,7 +564,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// scan character // scan character
int offset = fCurrentEntity.position; offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[fCurrentEntity.position++]; int c = fCurrentEntity.ch[fCurrentEntity.position++];
if (c == '\n' || (c == '\r' && isExternal)) { if (c == '\n' || (c == '\r' && isExternal)) {
fCurrentEntity.lineNumber++; fCurrentEntity.lineNumber++;
@ -561,10 +572,10 @@ public class XMLEntityScanner implements XMLLocator {
if (fCurrentEntity.position == fCurrentEntity.count) { if (fCurrentEntity.position == fCurrentEntity.count) {
invokeListeners(1); invokeListeners(1);
fCurrentEntity.ch[0] = (char)c; fCurrentEntity.ch[0] = (char)c;
load(1, false, false); load(1, true, false);
offset = 0; offset = 0;
} }
if (c == '\r' && isExternal) { if (c == '\r' && isExternal && fCurrentEntity.position < fCurrentEntity.count) {
if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') { if (fCurrentEntity.ch[fCurrentEntity.position++] != '\n') {
fCurrentEntity.position--; fCurrentEntity.position--;
} }
@ -614,7 +625,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// scan nmtoken // scan nmtoken
int offset = fCurrentEntity.position; offset = fCurrentEntity.position;
boolean vc = false; boolean vc = false;
char c; char c;
while (true){ while (true){
@ -695,7 +706,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// scan name // scan name
int offset = fCurrentEntity.position; offset = fCurrentEntity.position;
int length; int length;
if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) { if (XMLChar.isNameStart(fCurrentEntity.ch[offset])) {
if (++fCurrentEntity.position == fCurrentEntity.count) { if (++fCurrentEntity.position == fCurrentEntity.count) {
@ -788,7 +799,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// scan qualified name // scan qualified name
int offset = fCurrentEntity.position; offset = fCurrentEntity.position;
//making a check if if the specified character is a valid name start character //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. //as defined by production [5] in the XML 1.0 specification.
@ -1043,81 +1054,11 @@ public class XMLEntityScanner implements XMLLocator {
} }
// normalize newlines // normalize newlines
int offset = fCurrentEntity.position; if (normalizeNewlines(XML_VERSION_1_0, content, false, false, null)) {
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();
}
return -1; return -1;
} }
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
}
int c;
while (fCurrentEntity.position < fCurrentEntity.count) { while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++]; c = fCurrentEntity.ch[fCurrentEntity.position++];
if (!XMLChar.isContent(c)) { if (!XMLChar.isContent(c)) {
@ -1202,85 +1143,14 @@ public class XMLEntityScanner implements XMLLocator {
} }
// normalize newlines // normalize newlines
int offset = fCurrentEntity.position;
int c = fCurrentEntity.ch[offset];
int newlines = 0;
if(whiteSpaceInfoNeeded) if(whiteSpaceInfoNeeded)
whiteSpaceLen=0; 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 (normalizeNewlines(XML_VERSION_1_0, content, false, true, null)) {
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();
}
return -1; return -1;
} }
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
}
int c;
// scan literal value // scan literal value
for (; fCurrentEntity.position<fCurrentEntity.count; fCurrentEntity.position++) { for (; fCurrentEntity.position<fCurrentEntity.count; fCurrentEntity.position++) {
c = fCurrentEntity.ch[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 * @param whiteSpacePos position of a whitespace in the scanner entity buffer
*/ */
private void storeWhiteSpace(int whiteSpacePos) { void storeWhiteSpace(int whiteSpacePos) {
if (whiteSpaceLen >= whiteSpaceLookup.length) { if (whiteSpaceLen >= whiteSpaceLookup.length) {
int [] tmp = new int[whiteSpaceLookup.length + 100]; int [] tmp = new int[whiteSpaceLookup.length + 100];
System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length); System.arraycopy(whiteSpaceLookup, 0, tmp, 0, whiteSpaceLookup.length);
@ -1415,75 +1285,11 @@ public class XMLEntityScanner implements XMLLocator {
return false; return false;
} }
// normalize newlines if (normalizeNewlines(XML_VERSION_1_0, buffer, true, false, NameType.COMMENT)) {
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();
}
return true; return true;
} }
if (DEBUG_BUFFER) {
System.out.print("]newline, "+offset+", "+fCurrentEntity.position+": ");
print();
System.out.println();
}
}
int c;
// iterate over buffer looking for delimiter // iterate over buffer looking for delimiter
OUTER: while (fCurrentEntity.position < fCurrentEntity.count) { OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
c = fCurrentEntity.ch[fCurrentEntity.position++]; c = fCurrentEntity.ch[fCurrentEntity.position++];
@ -1570,7 +1376,7 @@ public class XMLEntityScanner implements XMLLocator {
} }
// skip character // skip character
int offset = fCurrentEntity.position; offset = fCurrentEntity.position;
int cc = fCurrentEntity.ch[fCurrentEntity.position]; int cc = fCurrentEntity.ch[fCurrentEntity.position];
if (cc == c) { if (cc == c) {
fCurrentEntity.position++; fCurrentEntity.position++;
@ -1587,26 +1393,6 @@ public class XMLEntityScanner implements XMLLocator {
} }
checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset); checkEntityLimit(nt, fCurrentEntity, offset, fCurrentEntity.position - offset);
return true; 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 // character was not skipped
@ -1659,7 +1445,7 @@ public class XMLEntityScanner implements XMLLocator {
// skip spaces // skip spaces
int c = fCurrentEntity.ch[fCurrentEntity.position]; int c = fCurrentEntity.ch[fCurrentEntity.position];
int offset = fCurrentEntity.position - 1; offset = fCurrentEntity.position - 1;
if (XMLChar.isSpace(c)) { if (XMLChar.isSpace(c)) {
do { do {
boolean entityChanged = false; boolean entityChanged = false;
@ -2332,5 +2118,86 @@ public class XMLEntityScanner implements XMLLocator {
} // skipDeclSpaces():boolean } // 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 } // 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 * 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 Eric Ye, IBM
* @author K.Venugopal SUN Microsystems * @author K.Venugopal SUN Microsystems
* @author Sunitha Reddy, SUN Microsystems * @author Sunitha Reddy, SUN Microsystems
* @LastModified: Feb 2020 * @LastModified: Aug 2021
*/ */
public abstract class XMLScanner public abstract class XMLScanner
implements XMLComponent { implements XMLComponent {
@ -956,12 +956,6 @@ public abstract class XMLScanner
System.out.println("** valueF: \"" System.out.println("** valueF: \""
+ stringBuffer.toString() + "\""); + 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)) { } else if (c != -1 && XMLChar.isHighSurrogate(c)) {
fStringBuffer3.clear(); fStringBuffer3.clear();
if (scanSurrogates(fStringBuffer3)) { if (scanSurrogates(fStringBuffer3)) {

View file

@ -1,6 +1,5 @@
/* /*
* reserved comment block * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * 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 Andy Clark, IBM
* @author Eric Ye, IBM * @author Eric Ye, IBM
* * @LastModified: Aug 2021
*/ */
public class XMLStringBuffer public class XMLStringBuffer
extends XMLString { extends XMLString {
//
// Constants
//
/** Default buffer size (32). */
public static final int DEFAULT_SIZE = 32;
// //
// Data // Data
// //
@ -112,79 +103,4 @@ extends XMLString {
length = 0; 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 } // class XMLStringBuffer

View file

@ -1,6 +1,5 @@
/* /*
* reserved comment block * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * 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 Eric Ye, IBM
* @author Andy Clark, IBM * @author Andy Clark, IBM
* * @LastModified: Aug 2021
*/ */
public class XMLString { public class XMLString {
/** Default buffer size (32). */
public static final int DEFAULT_SIZE = 32;
// //
// Data // Data
@ -189,4 +190,78 @@ public class XMLString {
return length > 0 ? new String(ch, offset, length) : ""; return length > 0 ? new String(ch, offset, length) : "";
} // toString():String } // 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 } // class XMLString

View file

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

View file

@ -27,6 +27,7 @@ package com.sun.java.accessibility.internal;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.util.*; import java.util.*;
import java.lang.*; import java.lang.*;
import java.lang.reflect.*; import java.lang.reflect.*;
@ -478,6 +479,9 @@ public final class AccessBridge {
if (parent == null) { if (parent == null) {
return null; return null;
} }
Point userSpaceXY = AccessibilityGraphicsEnvironment.toUserSpace(x, y);
x = userSpaceXY.x;
y = userSpaceXY.y;
if (windowHandleToContextMap != null && if (windowHandleToContextMap != null &&
windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) { windowHandleToContextMap.containsValue(getRootAccessibleContext(parent))) {
// Path for applications that register their top-level // Path for applications that register their top-level
@ -1593,6 +1597,8 @@ public final class AccessBridge {
if (p != null) { if (p != null) {
r.x = p.x; r.x = p.x;
r.y = p.y; r.y = p.y;
r = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(r);
return r; return r;
} }
} catch (Exception e) { } catch (Exception e) {
@ -2257,6 +2263,7 @@ public final class AccessBridge {
if (s != null && s.equals("\n")) { if (s != null && s.equals("\n")) {
rect.width = 0; rect.width = 0;
} }
rect = AccessibilityGraphicsEnvironment.toDeviceSpaceAbs(rect);
return 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 * Setup data to copy to target process
*/ */
memset(&data, 0, sizeof(data));
data._GetModuleHandle = _GetModuleHandle; data._GetModuleHandle = _GetModuleHandle;
data._GetProcAddress = _GetProcAddress; data._GetProcAddress = _GetProcAddress;

View file

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

View file

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

View file

@ -47,6 +47,9 @@ class FixedLengthOutputStream extends FilterOutputStream
FixedLengthOutputStream (ExchangeImpl t, OutputStream src, long len) { FixedLengthOutputStream (ExchangeImpl t, OutputStream src, long len) {
super (src); super (src);
if (len < 0) {
throw new IllegalArgumentException("Content-Length: " + len);
}
this.t = t; this.t = t;
this.remaining = len; 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -208,7 +208,9 @@ class Request {
"sun.net.httpserver.maxReqHeaders) exceeded, " + "sun.net.httpserver.maxReqHeaders) exceeded, " +
ServerConfig.getMaxReqHeaders() + "."); ServerConfig.getMaxReqHeaders() + ".");
} }
if (k == null) { // Headers disallows null keys, use empty string
k = ""; // instead to represent invalid key
}
hdrs.add (k,v); hdrs.add (k,v);
len = 0; len = 0;
} }

View file

@ -630,6 +630,11 @@ class ServerImpl implements TimeSource {
headerValue = headers.getFirst("Content-Length"); headerValue = headers.getFirst("Content-Length");
if (headerValue != null) { if (headerValue != null) {
clen = Long.parseLong(headerValue); clen = Long.parseLong(headerValue);
if (clen < 0) {
reject(Code.HTTP_BAD_REQUEST, requestLine,
"Illegal Content-Length value");
return;
}
} }
if (clen == 0) { if (clen == 0) {
requestCompleted(connection); 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 (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); ok &= testDeserializedLength(elements, loadFactor);
} }
} }

View file

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