summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorTaiju Tsuiki <tzik@google.com>2015-04-13 14:21:00 +0900
committerAndreas Gampe <agampe@google.com>2015-06-19 18:28:41 -0700
commitcbf5d89665cfb48778b2946794fbea43067ff04a (patch)
tree4d76a5b5a14cac444f405562f458511af25db02f /runtime
parent1bd841a26a0810decbd3cd9dcc3c0dca5773dc2b (diff)
downloadart-cbf5d89665cfb48778b2946794fbea43067ff04a.zip
art-cbf5d89665cfb48778b2946794fbea43067ff04a.tar.gz
art-cbf5d89665cfb48778b2946794fbea43067ff04a.tar.bz2
ART: Check var-arg count earlier in method verifier
Check the count in vararg instructions before filling the temp array. Avoids a DCHECK. Bug: 21869663 Bug: 20170976 (cherry picked from commit 29498a23bcfe47a7134552aacad5524ecb484a49) Change-Id: I1ff93502ab84c5967ad54d1b50dba517da791637
Diffstat (limited to 'runtime')
-rw-r--r--runtime/verifier/method_verifier.cc14
1 files changed, 7 insertions, 7 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index aa54b17..06ebf8b 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -857,14 +857,18 @@ bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_of
case Instruction::kVerifyVarArgNonZero:
// Fall-through.
case Instruction::kVerifyVarArg: {
- if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && inst->VRegA() <= 0) {
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
+ // Instructions that can actually return a negative value shouldn't have this flag.
+ uint32_t v_a = dchecked_integral_cast<uint32_t>(inst->VRegA());
+ if ((inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && v_a == 0) ||
+ v_a > Instruction::kMaxVarArgRegs) {
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << v_a << ") in "
"non-range invoke";
return false;
}
+
uint32_t args[Instruction::kMaxVarArgRegs];
inst->GetVarArgs(args);
- result = result && CheckVarArgRegs(inst->VRegA(), args);
+ result = result && CheckVarArgRegs(v_a, args);
break;
}
case Instruction::kVerifyVarArgRangeNonZero:
@@ -1175,10 +1179,6 @@ bool MethodVerifier::CheckSwitchTargets(uint32_t cur_offset) {
}
bool MethodVerifier::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) {
- if (vA > Instruction::kMaxVarArgRegs) {
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << vA << ") in non-range invoke)";
- return false;
- }
uint16_t registers_size = code_item_->registers_size_;
for (uint32_t idx = 0; idx < vA; idx++) {
if (arg[idx] >= registers_size) {