Don't update checksum if data ptr is null.
Passing a nullptr to adler32 resets it to its initial value.
Bug: 28874264
(cherry-picked from commit 2c6b49498e2f084ce217fcd3327103eadc1e0c37)
Change-Id: I9ac1b66004d4028a67aca18057c03ba9fb494041
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 5b19284..21e198c 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -448,23 +448,23 @@
}
TEST_F(OatTest, OatHeaderIsValid) {
- InstructionSet insn_set = kX86;
- std::string error_msg;
- std::unique_ptr<const InstructionSetFeatures> insn_features(
- InstructionSetFeatures::FromVariant(insn_set, "default", &error_msg));
- ASSERT_TRUE(insn_features.get() != nullptr) << error_msg;
- std::unique_ptr<OatHeader> oat_header(OatHeader::Create(insn_set,
- insn_features.get(),
- 0u,
- nullptr));
- ASSERT_NE(oat_header.get(), nullptr);
- ASSERT_TRUE(oat_header->IsValid());
+ InstructionSet insn_set = kX86;
+ std::string error_msg;
+ std::unique_ptr<const InstructionSetFeatures> insn_features(
+ InstructionSetFeatures::FromVariant(insn_set, "default", &error_msg));
+ ASSERT_TRUE(insn_features.get() != nullptr) << error_msg;
+ std::unique_ptr<OatHeader> oat_header(OatHeader::Create(insn_set,
+ insn_features.get(),
+ 0u,
+ nullptr));
+ ASSERT_NE(oat_header.get(), nullptr);
+ ASSERT_TRUE(oat_header->IsValid());
- char* magic = const_cast<char*>(oat_header->GetMagic());
- strcpy(magic, ""); // bad magic
- ASSERT_FALSE(oat_header->IsValid());
- strcpy(magic, "oat\n000"); // bad version
- ASSERT_FALSE(oat_header->IsValid());
+ char* magic = const_cast<char*>(oat_header->GetMagic());
+ strcpy(magic, ""); // bad magic
+ ASSERT_FALSE(oat_header->IsValid());
+ strcpy(magic, "oat\n000"); // bad version
+ ASSERT_FALSE(oat_header->IsValid());
}
TEST_F(OatTest, EmptyTextSection) {
@@ -766,4 +766,28 @@
TestZipFileInput(true);
}
+TEST_F(OatTest, UpdateChecksum) {
+ InstructionSet insn_set = kX86;
+ std::string error_msg;
+ std::unique_ptr<const InstructionSetFeatures> insn_features(
+ InstructionSetFeatures::FromVariant(insn_set, "default", &error_msg));
+ ASSERT_TRUE(insn_features.get() != nullptr) << error_msg;
+ std::unique_ptr<OatHeader> oat_header(OatHeader::Create(insn_set,
+ insn_features.get(),
+ 0u,
+ nullptr));
+ // The starting adler32 value is 1.
+ EXPECT_EQ(1U, oat_header->GetChecksum());
+
+ oat_header->UpdateChecksum(OatHeader::kOatMagic, sizeof(OatHeader::kOatMagic));
+ EXPECT_EQ(64291151U, oat_header->GetChecksum());
+
+ // Make sure that null data does not reset the checksum.
+ oat_header->UpdateChecksum(nullptr, 0);
+ EXPECT_EQ(64291151U, oat_header->GetChecksum());
+
+ oat_header->UpdateChecksum(OatHeader::kOatMagic, sizeof(OatHeader::kOatMagic));
+ EXPECT_EQ(216138397U, oat_header->GetChecksum());
+}
+
} // namespace art
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 80231f3..aab0e81 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -182,8 +182,12 @@
void OatHeader::UpdateChecksum(const void* data, size_t length) {
DCHECK(IsValid());
- const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
- adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
+ if (data != nullptr) {
+ const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
+ adler32_checksum_ = adler32(adler32_checksum_, bytes, length);
+ } else {
+ DCHECK_EQ(0U, length);
+ }
}
InstructionSet OatHeader::GetInstructionSet() const {