Fix ObjectReference.InvokeMethod.
This probably broke when I rewrote the object registry, but because
the test was so crap, we may have gotten away with passing bad pointers.
(Though for me, CheckJNI was catching this.)
While I'm here, fix the argument checking, which was previously
very weak; we'd accept any reference type rather than instances of
the parameter's specific type.
Change-Id: I08c001cabde02a0509fe28df17523a2d2519d1ca
diff --git a/src/debugger.cc b/src/debugger.cc
index 64be25c..fdab63a 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -2690,10 +2690,27 @@
return JDWP::ERR_ILLEGAL_ARGUMENT;
}
const char* shorty = mh.GetShorty();
+ const DexFile::TypeList* types = mh.GetParameterTypeList();
for (size_t i = 0; i < arg_count; ++i) {
if (shorty[i + 1] != JdwpTagToShortyChar(arg_types[i])) {
return JDWP::ERR_ILLEGAL_ARGUMENT;
}
+
+ if (shorty[i + 1] == 'L') {
+ // Did we really get an argument of an appropriate reference type?
+ mirror::Class* parameter_type = mh.GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
+ mirror::Object* argument = gRegistry->Get<mirror::Object*>(arg_values[i]);
+ if (argument == ObjectRegistry::kInvalidObject) {
+ return JDWP::ERR_INVALID_OBJECT;
+ }
+ if (!argument->InstanceOf(parameter_type)) {
+ return JDWP::ERR_ILLEGAL_ARGUMENT;
+ }
+
+ // Turn the on-the-wire ObjectId into a jobject.
+ jvalue& v = reinterpret_cast<jvalue&>(arg_values[i]);
+ v.l = gRegistry->GetJObject(arg_values[i]);
+ }
}
req->receiver_ = receiver;
diff --git a/src/jdwp/object_registry.h b/src/jdwp/object_registry.h
index 734bb86..d0ea59d 100644
--- a/src/jdwp/object_registry.h
+++ b/src/jdwp/object_registry.h
@@ -76,7 +76,7 @@
// Returned by Get when passed an invalid object id.
static mirror::Object* const kInvalidObject;
- // This is needed to get the jobject of a thread instead of the Object*.
+ // This is needed to get the jobject instead of the Object*.
// Avoid using this and use standard Get when possible.
jobject GetJObject(JDWP::ObjectId id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/src/object_utils.h b/src/object_utils.h
index 8a4bf77..9ad2b79 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -480,27 +480,6 @@
return GetDexFile().GetProtoParameters(proto);
}
- mirror::ObjectArray<mirror::Class>* GetParameterTypes(Thread* self)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::TypeList* params = GetParameterTypeList();
- uint32_t num_params = params == NULL ? 0 : params->Size();
- SirtRef<mirror::ObjectArray<mirror::Class> >
- result(self, GetClassLinker()->AllocClassArray(self, num_params));
- if (UNLIKELY(result.get() == NULL)) {
- CHECK(self->IsExceptionPending());
- return NULL;
- }
- for (uint32_t i = 0; i < num_params; i++) {
- mirror::Class* param_type = GetClassFromTypeIdx(params->GetTypeItem(i).type_idx_);
- if (param_type == NULL) {
- DCHECK(Thread::Current()->IsExceptionPending());
- return NULL;
- }
- result->Set(i, param_type);
- }
- return result.get();
- }
-
mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());