diff options
author | Jeff Hao <jeffhao@google.com> | 2013-09-03 19:07:00 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2013-09-24 15:18:36 -0700 |
commit | a3faaf4bece7f42529c013fe87bd41de59798656 (patch) | |
tree | 933e312a4aa4d69b2d7da7eda4d592419cec4729 /runtime/interpreter/interpreter_common.cc | |
parent | a9a624b2be2180e6bd33f02c89fb8521376a2e8c (diff) | |
download | art-a3faaf4bece7f42529c013fe87bd41de59798656.zip art-a3faaf4bece7f42529c013fe87bd41de59798656.tar.gz art-a3faaf4bece7f42529c013fe87bd41de59798656.tar.bz2 |
Fix handling of unresolved references in verifier.
The verifier should not treat use of unresolved references as a reason to reject
the entire class. Instead, the verifier treats the instruction as a throw. If
that class is run, the interpreter with extra checks will throw an exception.
Bug: 10457426
Change-Id: I3799da843a7ffb3519bbf6dc13a6276519d9cb95
Diffstat (limited to 'runtime/interpreter/interpreter_common.cc')
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 86a6aea..36b250c 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -22,6 +22,7 @@ namespace interpreter { template<InvokeType type, bool is_range, bool do_access_check> bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, JValue* result) { + bool do_assignability_check = do_access_check; uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); Object* receiver = (type == kStatic) ? NULL : shadow_frame.GetVRegReference(vregC); @@ -61,6 +62,10 @@ bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, ++cur_reg; } + const DexFile::TypeList* params; + if (do_assignability_check) { + params = mh.GetParameterTypeList(); + } size_t arg_offset = (receiver == NULL) ? 0 : 1; const char* shorty = mh.GetShorty(); uint32_t arg[5]; @@ -73,6 +78,23 @@ bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, switch (shorty[shorty_pos + 1]) { case 'L': { Object* o = shadow_frame.GetVRegReference(arg_pos); + if (do_assignability_check && o != NULL) { + Class* arg_type = mh.GetClassFromTypeIdx(params->GetTypeItem(shorty_pos).type_idx_); + if (arg_type == NULL) { + CHECK(self->IsExceptionPending()); + return false; + } + if (!o->VerifierInstanceOf(arg_type)) { + // This should never happen. + self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(), + "Ljava/lang/VirtualMachineError;", + "Invoking %s with bad arg %d, type '%s' not instance of '%s'", + mh.GetName(), shorty_pos, + ClassHelper(o->GetClass()).GetDescriptor(), + ClassHelper(arg_type).GetDescriptor()); + return false; + } + } new_shadow_frame->SetVRegReference(cur_reg, o); break; } |