Fix potential null read for truncated dex files

In the case where a dex file is truncated, don't attempt to read the
header.

Added regression test.

Bug: 63756964
Bug: 72826975
Test: mm test-art-host-gtest-dex2oat_test -j64
Test: mm test-art-target-gtest-dex2oat_test -j64
Change-Id: I9bd6bb445ef2eb1c961044f43ac71f04ef8c04a5
diff --git a/runtime/dex/dex_file_loader.cc b/runtime/dex/dex_file_loader.cc
index 0f2758e..2c75c5b 100644
--- a/runtime/dex/dex_file_loader.cc
+++ b/runtime/dex/dex_file_loader.cc
@@ -319,7 +319,7 @@
     *verify_result = VerifyResult::kVerifyNotAttempted;
   }
   std::unique_ptr<DexFile> dex_file;
-  if (StandardDexFile::IsMagicValid(base)) {
+  if (size >= sizeof(StandardDexFile::Header) && StandardDexFile::IsMagicValid(base)) {
     if (data_size != 0) {
       CHECK_EQ(base, data_base) << "Unsupported for standard dex";
     }
@@ -329,7 +329,7 @@
                                        location_checksum,
                                        oat_dex_file,
                                        container));
-  } else if (CompactDexFile::IsMagicValid(base)) {
+  } else if (size >= sizeof(CompactDexFile::Header) && CompactDexFile::IsMagicValid(base)) {
     if (data_base == nullptr) {
       // TODO: Is there a clean way to support both an explicit data section and reading the one
       // from the header.
@@ -346,6 +346,8 @@
                                       location_checksum,
                                       oat_dex_file,
                                       container));
+  } else {
+    *error_msg = "Invalid or truncated dex file";
   }
   if (dex_file == nullptr) {
     *error_msg = StringPrintf("Failed to open dex file '%s' from memory: %s", location.c_str(),