7186957: Improve Pack200 data validation

Reviewed-by: jrose, jjh, mschoene
This commit is contained in:
Kumar Srinivasan 2012-10-16 12:35:22 -07:00
parent 1ee5b4509e
commit 0c4da1ece1
5 changed files with 36 additions and 7 deletions

View File

@ -1000,7 +1000,6 @@ class BandStructure {
/** Write a constant pool reference. */
public void putRef(Entry e) {
assert(index != null);
addValue(encodeRefOrNull(e, index));
}
public void putRef(Entry e, Index index) {
@ -1052,6 +1051,8 @@ class BandStructure {
int encodeRef(Entry e, Index ix) {
if (ix == null)
throw new RuntimeException("null index for " + e.stringValue());
int coding = ix.indexOf(e);
if (verbose > 2)
Utils.log.fine("putRef "+coding+" => "+e);

View File

@ -1381,6 +1381,8 @@ class ConstantPool {
/** Index of all CP entries of a given tag and class. */
public Index getMemberIndex(byte tag, ClassEntry classRef) {
if (classRef == null)
throw new RuntimeException("missing class reference for " + tagName(tag));
if (indexByTagAndClass == null)
indexByTagAndClass = new Index[CONSTANT_Limit][];
Index allClasses = getIndexByTag(CONSTANT_Class);

View File

@ -187,6 +187,10 @@ void band::setIndexByTag(byte tag) {
entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) {
CHECK_0;
if (ix_ == NULL) {
abort("no index");
return NULL;
}
assert(ix_->ixTag == ixTag
|| ((ixTag == CONSTANT_All ||
ixTag == CONSTANT_LoadableValue ||

View File

@ -99,8 +99,8 @@ struct band {
int getByte() { assert(ix == null); return vs[0].getByte(); }
int getInt() { assert(ix == null); return vs[0].getInt(); }
entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); }
entry* getRef() { assert(ix != null); return getRefCommon(ix, false); }
entry* getRefN() { return getRefCommon(ix, true); }
entry* getRef() { return getRefCommon(ix, false); }
entry* getRefUsing(cpindex* ix2)
{ assert(ix == null); return getRefCommon(ix2, true); }
entry* getRefCommon(cpindex* ix, bool nullOK);

View File

@ -281,11 +281,13 @@ int entry::typeSize() {
}
inline cpindex* cpool::getFieldIndex(entry* classRef) {
if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+0];
}
inline cpindex* cpool::getMethodIndex(entry* classRef) {
if (classRef == NULL) { abort("missing class reference"); return NULL; }
assert(classRef->tagMatches(CONSTANT_Class));
assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
return &member_indexes[classRef->inord*2+1];
@ -1289,6 +1291,7 @@ void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 2);
e.refs[0] = cp_band1.getRef();
CHECK;
e.refs[1] = cp_band2.getRef();
CHECK;
}
@ -1369,6 +1372,7 @@ void unpacker::read_method_type(entry* cpMap, int len) {
entry& e = cpMap[i];
e.refs = U_NEW(entry*, e.nrefs = 1);
e.refs[0] = cp_MethodType.getRef();
CHECK;
}
}
@ -2104,6 +2108,7 @@ void unpacker::read_attr_defs() {
int attrc = ADH_BYTE_CONTEXT(header);
int idx = ADH_BYTE_INDEX(header);
entry* name = attr_definition_name.getRef();
CHECK;
entry* layout = attr_definition_layout.getRef();
CHECK;
attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
@ -2208,7 +2213,9 @@ void unpacker::read_ics() {
if (ics[i].name == NO_ENTRY_YET) {
// Long form.
ics[i].outer = ic_outer_class.getRefN();
CHECK;
ics[i].name = ic_name.getRefN();
CHECK;
} else {
// Fill in outer and name based on inner.
bytes& n = ics[i].inner->value.b;
@ -2724,6 +2731,7 @@ void unpacker::putlayout(band** body) {
e = b.getRefUsing(cp.getKQIndex());
else
e = b.getRefN();
CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1ref(e); break;
@ -4006,6 +4014,7 @@ void unpacker::write_bc_ops() {
NOT_PRODUCT(bc_superfield.setIndex(null));
NOT_PRODUCT(bc_supermethod.setIndex(null));
}
CHECK;
for (int curIP = 0; ; curIP++) {
int curPC = (int)(wpoffset() - codeBase);
@ -4119,7 +4128,8 @@ void unpacker::write_bc_ops() {
int coding = bc_initref.getInt();
// Find the nth overloading of <init> in classRef.
entry* ref = null;
cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef);
cpindex* ix = cp.getMethodIndex(classRef);
CHECK;
for (int j = 0, which_init = 0; ; j++) {
ref = (ix == null)? null: ix->get(j);
if (ref == null) break; // oops, bad input
@ -4396,6 +4406,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
aname = cp.sym[cpool::s_EnclosingMethod];
putref(class_EnclosingMethod_RC.getRefN());
CHECK_0;
putref(class_EnclosingMethod_RDN.getRefN());
break;
@ -4414,6 +4425,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
putu2(count = method_Exceptions_N.getInt());
for (j = 0; j < count; j++) {
putref(method_Exceptions_RC.getRefN());
CHECK_0;
}
break;
@ -4437,16 +4449,18 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
// (253) [(1)(2)(2)]
// (254) [(1)(2)(2)(2)]
putu2(code_StackMapTable_offset.getInt());
CHECK_0;
for (int k = (tag - 251); k > 0; k--) {
put_stackmap_type();
CHECK_0;
}
} else {
// (255) [(1)NH[(2)]NH[(2)]]
putu2(code_StackMapTable_offset.getInt());
putu2(j2 = code_StackMapTable_local_N.getInt());
while (j2-- > 0) put_stackmap_type();
while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
putu2(j2 = code_StackMapTable_stack_N.getInt());
while (j2-- > 0) put_stackmap_type();
while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
}
}
break;
@ -4470,7 +4484,9 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
CHECK_0;
putu2(code_LocalVariableTable_slot.getInt());
}
break;
@ -4485,7 +4501,9 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
CHECK_0;
putu2(code_LocalVariableTypeTable_slot.getInt());
}
break;
@ -4513,7 +4531,7 @@ int unpacker::write_attrs(int attrc, julong indexBits) {
break;
}
}
CHECK_0;
if (aname == null) {
// Unparse a compressor-defined attribute.
layout_definition* lo = ad.getLayout(idx);
@ -4669,7 +4687,9 @@ int unpacker::write_ics(int naOffset, int na) {
flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
extra_ic.flags = flags;
extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
CHECK_0;
extra_ic.name = class_InnerClasses_name_RUN.getRefN();
CHECK_0;
// Detect if this is an exact copy of the global tuple.
if (global_ic != null) {
if (global_ic->flags != extra_ic.flags ||
@ -4778,6 +4798,7 @@ void unpacker::write_classfile_tail() {
julong indexMask = ad.flagIndexMask();
cur_class = class_this.getRef();
CHECK;
cur_super = class_super.getRef();
CHECK;
@ -4791,6 +4812,7 @@ void unpacker::write_classfile_tail() {
putu2(num = class_interface_count.getInt());
for (i = 0; i < num; i++) {
putref(class_interface.getRef());
CHECK;
}
write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);