mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8175383: JVM should throw NCDFE if ACC_MODULE and CONSTANT_Module/Package are set
If bad constant is seen, save it to throw CFE if ACC_MODULE is not in access_flags Reviewed-by: dholmes, acorn, lfoltan, gtriantafill
This commit is contained in:
parent
5cdba20f81
commit
b7121021af
4 changed files with 369 additions and 5 deletions
|
@ -105,6 +105,12 @@
|
|||
|
||||
#define JAVA_9_VERSION 53
|
||||
|
||||
void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
|
||||
assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
|
||||
"Unexpected bad constant pool entry");
|
||||
if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
|
||||
}
|
||||
|
||||
void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
|
||||
ConstantPool* cp,
|
||||
const int length,
|
||||
|
@ -302,6 +308,18 @@ void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const s
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 19:
|
||||
case 20: {
|
||||
// Record that an error occurred in these two cases but keep parsing so
|
||||
// that ACC_Module can be checked for in the access_flags. Need to
|
||||
// throw NoClassDefFoundError in that case.
|
||||
if (_major_version >= JAVA_9_VERSION) {
|
||||
cfs->guarantee_more(3, CHECK);
|
||||
cfs->get_u2_fast();
|
||||
set_class_bad_constant_seen(tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
classfile_parse_error("Unknown constant tag %u in class file %s",
|
||||
tag,
|
||||
|
@ -359,14 +377,18 @@ PRAGMA_DIAG_POP
|
|||
#endif
|
||||
|
||||
void ClassFileParser::parse_constant_pool(const ClassFileStream* const stream,
|
||||
ConstantPool* const cp,
|
||||
const int length,
|
||||
TRAPS) {
|
||||
ConstantPool* const cp,
|
||||
const int length,
|
||||
TRAPS) {
|
||||
assert(cp != NULL, "invariant");
|
||||
assert(stream != NULL, "invariant");
|
||||
|
||||
// parsing constant pool entries
|
||||
parse_constant_pool_entries(stream, cp, length, CHECK);
|
||||
if (class_bad_constant_seen() != 0) {
|
||||
// a bad CP entry has been detected previously so stop parsing and just return.
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 1; // declared outside of loops for portability
|
||||
|
||||
|
@ -5558,6 +5580,7 @@ ClassFileParser::ClassFileParser(ClassFileStream* stream,
|
|||
_protection_domain(protection_domain),
|
||||
_access_flags(),
|
||||
_pub_level(pub_level),
|
||||
_bad_constant_seen(0),
|
||||
_synthetic_flag(false),
|
||||
_sde_length(false),
|
||||
_sde_buffer(NULL),
|
||||
|
@ -5765,8 +5788,14 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream,
|
|||
|
||||
verify_legal_class_modifiers(flags, CHECK);
|
||||
|
||||
_access_flags.set_flags(flags);
|
||||
short bad_constant = class_bad_constant_seen();
|
||||
if (bad_constant != 0) {
|
||||
// Do not throw CFE until after the access_flags are checked because if
|
||||
// ACC_MODULE is set in the access flags, then NCDFE must be thrown, not CFE.
|
||||
classfile_parse_error("Unknown constant tag %u in class file %s", bad_constant, CHECK);
|
||||
}
|
||||
|
||||
_access_flags.set_flags(flags);
|
||||
|
||||
// This class and superclass
|
||||
_this_class_index = stream->get_u2_fast();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue