< prev index next >
src/share/vm/classfile/classFileParser.cpp
Print this page
@@ -103,10 +103,16 @@
// Extension method support.
#define JAVA_8_VERSION 52
#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,
TRAPS) {
assert(stream != NULL, "invariant");
@@ -300,10 +306,22 @@
} else {
cp->symbol_at_put(index, result);
}
break;
}
+ case 19:
+ case 20: {
+ // Record that an error occured 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,
CHECK);
break;
@@ -365,10 +383,20 @@
assert(cp != NULL, "invariant");
assert(stream != NULL, "invariant");
// parsing constant pool entries
parse_constant_pool_entries(stream, cp, length, CHECK);
+ short bad_constant = class_bad_constant_seen();
+ if (bad_constant != 0) {
+ // Either a CONSTANT_Module or CONSTANT_Package entry was found in the constant
+ // pool. So, stop parsing and return. The caller will decide whether to throw
+ // NCDFE if it finds ACC_MODULE in the class's access_flags or throw CFE for
+ // the bad constant pool entry.
+ assert((bad_constant == 19 || bad_constant == 20) && _major_version >= JAVA_9_VERSION,
+ "Unexpected bad constant pool entry");
+ return;
+ }
int index = 1; // declared outside of loops for portability
// first verification pass - validate cross references
// and fixup class and string constants
@@ -5556,10 +5584,11 @@
_num_miranda_methods(0),
_rt(REF_NONE),
_protection_domain(protection_domain),
_access_flags(),
_pub_level(pub_level),
+ _bad_constant_seen(0),
_synthetic_flag(false),
_sde_length(false),
_sde_buffer(NULL),
_sourcefile_index(0),
_generic_signature_index(0),
@@ -5763,12 +5792,18 @@
flags |= JVM_ACC_ABSTRACT;
}
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();
check_property(
valid_cp_range(_this_class_index, cp_size) &&
< prev index next >