8187254: MethodType allows unvalidated parameter types

Reviewed-by: mchung, jrose
This commit is contained in:
Paul Sandoz 2017-12-12 09:33:37 -08:00
parent 72e7a31529
commit 3246c46f41

View File

@ -105,23 +105,10 @@ class MethodType implements java.io.Serializable {
private @Stable String methodDescriptor; // cache for toMethodDescriptorString private @Stable String methodDescriptor; // cache for toMethodDescriptorString
/** /**
* Check the given parameters for validity and store them into the final fields. * Constructor that performs no copying or validation.
* Should only be called from the factory method makeImpl
*/ */
private MethodType(Class<?> rtype, Class<?>[] ptypes, boolean trusted) { private MethodType(Class<?> rtype, Class<?>[] ptypes) {
checkRtype(rtype);
checkPtypes(ptypes);
this.rtype = rtype;
// defensively copy the array passed in by the user
this.ptypes = trusted ? ptypes : Arrays.copyOf(ptypes, ptypes.length);
}
/**
* Construct a temporary unchecked instance of MethodType for use only as a key to the intern table.
* Does not check the given parameters for validity, and must discarded (if untrusted) or checked
* (if trusted) after it has been used as a searching key.
* The parameters are reversed for this constructor, so that it is not accidentally used.
*/
private MethodType(Class<?>[] ptypes, Class<?> rtype) {
this.rtype = rtype; this.rtype = rtype;
this.ptypes = ptypes; this.ptypes = ptypes;
} }
@ -308,18 +295,21 @@ class MethodType implements java.io.Serializable {
if (ptypes.length == 0) { if (ptypes.length == 0) {
ptypes = NO_PTYPES; trusted = true; ptypes = NO_PTYPES; trusted = true;
} }
MethodType primordialMT = new MethodType(ptypes, rtype); MethodType primordialMT = new MethodType(rtype, ptypes);
MethodType mt = internTable.get(primordialMT); MethodType mt = internTable.get(primordialMT);
if (mt != null) if (mt != null)
return mt; return mt;
// promote the object to the Real Thing, and reprobe // promote the object to the Real Thing, and reprobe
MethodType.checkRtype(rtype);
if (trusted) { if (trusted) {
MethodType.checkRtype(rtype);
MethodType.checkPtypes(ptypes); MethodType.checkPtypes(ptypes);
mt = primordialMT; mt = primordialMT;
} else { } else {
mt = new MethodType(rtype, ptypes, false); // Make defensive copy then validate
ptypes = Arrays.copyOf(ptypes, ptypes.length);
MethodType.checkPtypes(ptypes);
mt = new MethodType(rtype, ptypes);
} }
mt.form = MethodTypeForm.findForm(mt); mt.form = MethodTypeForm.findForm(mt);
return internTable.add(mt); return internTable.add(mt);