Another fix for external bug 2711 (over-eager conflicting class rejection).
The validateSuperDescriptors() test also checks for conflicts with
interface classes, and wasn't doing that quite right. We need to compare
every method declared by an interface against the class' implementation
of it. Methods implemented by superclasses are now tested in the context
of the superclass, not the current class.
This is a one-word fix + comments and new/updated tests.
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 0adced8..999a1a1 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -4053,6 +4053,9 @@
* We need to do this even for the stuff inherited from Object,
* because it's possible that the new class loader has redefined
* a basic class like String.
+ *
+ * We don't need to check stuff defined in a superclass because
+ * it was checked when the superclass was loaded.
*/
const Method* meth;
@@ -4075,7 +4078,12 @@
}
/*
- * Check all interfaces we implement.
+ * Check the methods defined by this class against the interfaces it
+ * implements. If we inherited the implementation from a superclass,
+ * we have to check it against the superclass (which might be in a
+ * different class loader). If the superclass also implements the
+ * interface, we could skip the check since by definition it was
+ * performed when the class was loaded.
*/
for (i = 0; i < clazz->iftableCount; i++) {
const InterfaceEntry* iftable = &clazz->iftable[i];
@@ -4091,7 +4099,7 @@
vtableIndex = iftable->methodIndexArray[j];
meth = clazz->vtable[vtableIndex];
- if (!checkMethodDescriptorClasses(meth, iface, clazz)) {
+ if (!checkMethodDescriptorClasses(meth, iface, meth->clazz)) {
LOGW("Method mismatch: %s in %s (cl=%p) and "
"iface %s (cl=%p)\n",
meth->name, clazz->descriptor, clazz->classLoader,