/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "dex_file_verifier.h"

#include "sys/mman.h"
#include "zlib.h"
#include <functional>
#include <memory>

#include "base/unix_file/fd_file.h"
#include "base/bit_utils.h"
#include "base/macros.h"
#include "common_runtime_test.h"
#include "dex_file-inl.h"
#include "dex_file_types.h"
#include "leb128.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-inl.h"
#include "utils.h"

namespace art {

// Make the Dex file version 37.
static void MakeDexVersion37(DexFile* dex_file) {
  size_t offset = OFFSETOF_MEMBER(DexFile::Header, magic_) + 6;
  CHECK_EQ(*(dex_file->Begin() + offset), '5');
  *(const_cast<uint8_t*>(dex_file->Begin()) + offset) = '7';
}

static void FixUpChecksum(uint8_t* dex_file) {
  DexFile::Header* header = reinterpret_cast<DexFile::Header*>(dex_file);
  uint32_t expected_size = header->file_size_;
  uint32_t adler_checksum = adler32(0L, Z_NULL, 0);
  const uint32_t non_sum = sizeof(DexFile::Header::magic_) + sizeof(DexFile::Header::checksum_);
  const uint8_t* non_sum_ptr = dex_file + non_sum;
  adler_checksum = adler32(adler_checksum, non_sum_ptr, expected_size - non_sum);
  header->checksum_ = adler_checksum;
}

class DexFileVerifierTest : public CommonRuntimeTest {
 protected:
  DexFile* GetDexFile(const uint8_t* dex_bytes, size_t length) {
    return new DexFile(dex_bytes, length, "tmp", 0, nullptr);
  }

  void VerifyModification(const char* dex_file_base64_content,
                          const char* location,
                          const std::function<void(DexFile*)>& f,
                          const char* expected_error) {
    size_t length;
    std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(dex_file_base64_content, &length));
    CHECK(dex_bytes != nullptr);
    // Note: `dex_file` will be destroyed before `dex_bytes`.
    std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
    f(dex_file.get());
    FixUpChecksum(const_cast<uint8_t*>(dex_file->Begin()));

    static constexpr bool kVerifyChecksum = true;
    std::string error_msg;
    bool success = DexFileVerifier::Verify(dex_file.get(),
                                           dex_file->Begin(),
                                           dex_file->Size(),
                                           location,
                                           kVerifyChecksum,
                                           &error_msg);
    if (expected_error == nullptr) {
      EXPECT_TRUE(success) << error_msg;
    } else {
      EXPECT_FALSE(success) << "Expected " << expected_error;
      if (!success) {
        EXPECT_NE(error_msg.find(expected_error), std::string::npos) << error_msg;
      }
    }
  }
};

static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64,
                                                        const char* location,
                                                        std::string* error_msg) {
  // decode base64
  CHECK(base64 != nullptr);
  size_t length;
  std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(base64, &length));
  CHECK(dex_bytes.get() != nullptr);

  // write to provided file
  std::unique_ptr<File> file(OS::CreateEmptyFile(location));
  CHECK(file.get() != nullptr);
  if (!file->WriteFully(dex_bytes.get(), length)) {
    PLOG(FATAL) << "Failed to write base64 as dex file";
  }
  if (file->FlushCloseOrErase() != 0) {
    PLOG(FATAL) << "Could not flush and close test file.";
  }
  file.reset();

  // read dex file
  ScopedObjectAccess soa(Thread::Current());
  std::vector<std::unique_ptr<const DexFile>> tmp;
  bool success = DexFile::Open(location, location, true, error_msg, &tmp);
  CHECK(success) << error_msg;
  EXPECT_EQ(1U, tmp.size());
  std::unique_ptr<const DexFile> dex_file = std::move(tmp[0]);
  EXPECT_EQ(PROT_READ, dex_file->GetPermissions());
  EXPECT_TRUE(dex_file->IsReadOnly());
  return dex_file;
}

// To generate a base64 encoded Dex file (such as kGoodTestDex, below)
// from Smali files, use:
//
//   smali -o classes.dex class1.smali [class2.smali ...]
//   base64 classes.dex >classes.dex.base64

// For reference.
static const char kGoodTestDex[] =
    "ZGV4CjAzNQDrVbyVkxX1HljTznNf95AglkUAhQuFtmKkAgAAcAAAAHhWNBIAAAAAAAAAAAQCAAAN"
    "AAAAcAAAAAYAAACkAAAAAgAAALwAAAABAAAA1AAAAAQAAADcAAAAAQAAAPwAAACIAQAAHAEAAFoB"
    "AABiAQAAagEAAIEBAACVAQAAqQEAAL0BAADDAQAAzgEAANEBAADVAQAA2gEAAN8BAAABAAAAAgAA"
    "AAMAAAAEAAAABQAAAAgAAAAIAAAABQAAAAAAAAAJAAAABQAAAFQBAAAEAAEACwAAAAAAAAAAAAAA"
    "AAAAAAoAAAABAAEADAAAAAIAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAcAAAAAAAAA8wEAAAAAAAAB"
    "AAEAAQAAAOgBAAAEAAAAcBADAAAADgACAAAAAgAAAO0BAAAIAAAAYgAAABoBBgBuIAIAEAAOAAEA"
    "AAADAAY8aW5pdD4ABkxUZXN0OwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09i"
    "amVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AARUZXN0AAlUZXN0"
    "LmphdmEAAVYAAlZMAANmb28AA291dAAHcHJpbnRsbgABAAcOAAMABw54AAAAAgAAgYAEnAIBCbQC"
    "AAAADQAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAAAAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAQA"
    "AAABAAAA1AAAAAUAAAAEAAAA3AAAAAYAAAABAAAA/AAAAAEgAAACAAAAHAEAAAEQAAABAAAAVAEA"
    "AAIgAAANAAAAWgEAAAMgAAACAAAA6AEAAAAgAAABAAAA8wEAAAAQAAABAAAABAIAAA==";

TEST_F(DexFileVerifierTest, GoodDex) {
  ScratchFile tmp;
  std::string error_msg;
  std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex, tmp.GetFilename().c_str(),
                                                       &error_msg));
  ASSERT_TRUE(raw.get() != nullptr) << error_msg;
}

TEST_F(DexFileVerifierTest, MethodId) {
  // Class idx error.
  VerifyModification(
      kGoodTestDex,
      "method_id_class_idx",
      [](DexFile* dex_file) {
        DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
        method_id->class_idx_ = dex::TypeIndex(0xFF);
      },
      "could not find declaring class for direct method index 0");

  // Proto idx error.
  VerifyModification(
      kGoodTestDex,
      "method_id_proto_idx",
      [](DexFile* dex_file) {
        DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
        method_id->proto_idx_ = 0xFF;
      },
      "inter_method_id_item proto_idx");

  // Name idx error.
  VerifyModification(
      kGoodTestDex,
      "method_id_name_idx",
      [](DexFile* dex_file) {
        DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
        method_id->name_idx_ = dex::StringIndex(0xFF);
      },
      "String index not available for method flags verification");
}

// Method flags test class generated from the following smali code. The declared-synchronized
// flags are there to enforce a 3-byte uLEB128 encoding so we don't have to relayout
// the code, but we need to remove them before doing tests.
//
// .class public LMethodFlags;
// .super Ljava/lang/Object;
//
// .method public static constructor <clinit>()V
// .registers 1
//     return-void
// .end method
//
// .method public constructor <init>()V
// .registers 1
//     return-void
// .end method
//
// .method private declared-synchronized foo()V
// .registers 1
//     return-void
// .end method
//
// .method public declared-synchronized bar()V
// .registers 1
//     return-void
// .end method

static const char kMethodFlagsTestDex[] =
    "ZGV4CjAzNQCyOQrJaDBwiIWv5MIuYKXhxlLLsQcx5SwgAgAAcAAAAHhWNBIAAAAAAAAAAJgBAAAH"
    "AAAAcAAAAAMAAACMAAAAAQAAAJgAAAAAAAAAAAAAAAQAAACkAAAAAQAAAMQAAAA8AQAA5AAAAOQA"
    "AADuAAAA9gAAAAUBAAAZAQAAHAEAACEBAAACAAAAAwAAAAQAAAAEAAAAAgAAAAAAAAAAAAAAAAAA"
    "AAAAAAABAAAAAAAAAAUAAAAAAAAABgAAAAAAAAABAAAAAQAAAAAAAAD/////AAAAAHoBAAAAAAAA"
    "CDxjbGluaXQ+AAY8aW5pdD4ADUxNZXRob2RGbGFnczsAEkxqYXZhL2xhbmcvT2JqZWN0OwABVgAD"
    "YmFyAANmb28AAAAAAAAAAQAAAAAAAAAAAAAAAQAAAA4AAAABAAEAAAAAAAAAAAABAAAADgAAAAEA"
    "AQAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAADAQCJgASsAgGBgATAAgKCgAjU"
    "AgKBgAjoAgAACwAAAAAAAAABAAAAAAAAAAEAAAAHAAAAcAAAAAIAAAADAAAAjAAAAAMAAAABAAAA"
    "mAAAAAUAAAAEAAAApAAAAAYAAAABAAAAxAAAAAIgAAAHAAAA5AAAAAMQAAABAAAAKAEAAAEgAAAE"
    "AAAALAEAAAAgAAABAAAAegEAAAAQAAABAAAAmAEAAA==";

// Find the method data for the first method with the given name (from class 0). Note: the pointer
// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
// delta.
static const uint8_t* FindMethodData(const DexFile* dex_file,
                                     const char* name,
                                     /*out*/ uint32_t* method_idx = nullptr) {
  const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
  const uint8_t* class_data = dex_file->GetClassData(class_def);

  ClassDataItemIterator it(*dex_file, class_data);

  const uint8_t* trailing = class_data;
  // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
  // element has already been loaded into the iterator.
  DecodeUnsignedLeb128(&trailing);
  DecodeUnsignedLeb128(&trailing);
  DecodeUnsignedLeb128(&trailing);
  DecodeUnsignedLeb128(&trailing);

  // Skip all fields.
  while (it.HasNextStaticField() || it.HasNextInstanceField()) {
    trailing = it.DataPointer();
    it.Next();
  }

  while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
    uint32_t method_index = it.GetMemberIndex();
    dex::StringIndex name_index = dex_file->GetMethodId(method_index).name_idx_;
    const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
    const char* str = dex_file->GetStringData(string_id);
    if (strcmp(name, str) == 0) {
      if (method_idx != nullptr) {
        *method_idx = method_index;
      }
      DecodeUnsignedLeb128(&trailing);
      return trailing;
    }

    trailing = it.DataPointer();
    it.Next();
  }

  return nullptr;
}

// Set the method flags to the given value.
static void SetMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
  uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
  CHECK(method_flags_ptr != nullptr) << method;

    // Unroll this, as we only have three bytes, anyways.
  uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
  *(method_flags_ptr++) = (base1 | 0x80);
  mask >>= 7;

  uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
  *(method_flags_ptr++) = (base2 | 0x80);
  mask >>= 7;

  uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
  *method_flags_ptr = base3;
}

static uint32_t GetMethodFlags(DexFile* dex_file, const char* method) {
  const uint8_t* method_flags_ptr = const_cast<uint8_t*>(FindMethodData(dex_file, method));
  CHECK(method_flags_ptr != nullptr) << method;
  return DecodeUnsignedLeb128(&method_flags_ptr);
}

// Apply the given mask to method flags.
static void ApplyMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
  uint32_t value = GetMethodFlags(dex_file, method);
  value &= mask;
  SetMethodFlags(dex_file, method, value);
}

// Apply the given mask to method flags.
static void OrMaskToMethodFlags(DexFile* dex_file, const char* method, uint32_t mask) {
  uint32_t value = GetMethodFlags(dex_file, method);
  value |= mask;
  SetMethodFlags(dex_file, method, value);
}

// Set code_off to 0 for the method.
static void RemoveCode(DexFile* dex_file, const char* method) {
  const uint8_t* ptr = FindMethodData(dex_file, method);
  // Next is flags, pass.
  DecodeUnsignedLeb128(&ptr);

  // Figure out how many bytes the code_off is.
  const uint8_t* tmp = ptr;
  DecodeUnsignedLeb128(&tmp);
  size_t bytes = tmp - ptr;

  uint8_t* mod = const_cast<uint8_t*>(ptr);
  for (size_t i = 1; i < bytes; ++i) {
    *(mod++) = 0x80;
  }
  *mod = 0x00;
}

TEST_F(DexFileVerifierTest, MethodAccessFlagsBase) {
  // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
  VerifyModification(
      kMethodFlagsTestDex,
      "method_flags_ok",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
        ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
      },
      nullptr);
}

TEST_F(DexFileVerifierTest, MethodAccessFlagsConstructors) {
  // Make sure we still accept constructors without their flags.
  VerifyModification(
      kMethodFlagsTestDex,
      "method_flags_missing_constructor_tag_ok",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
        ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccConstructor);
        ApplyMaskToMethodFlags(dex_file, "<clinit>", ~kAccConstructor);
      },
      nullptr);

  constexpr const char* kConstructors[] = { "<clinit>", "<init>"};
  for (size_t i = 0; i < 2; ++i) {
    // Constructor with code marked native.
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_constructor_native",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
        },
        "has code, but is marked native or abstract");
    // Constructor with code marked abstract.
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_constructor_abstract",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
        },
        "has code, but is marked native or abstract");
    // Constructor as-is without code.
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_constructor_nocode",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          RemoveCode(dex_file, kConstructors[i]);
        },
        "has no code, but is not marked native or abstract");
    // Constructor without code marked native.
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_constructor_native_nocode",
        [&](DexFile* dex_file) {
          MakeDexVersion37(dex_file);
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kConstructors[i], kAccNative);
          RemoveCode(dex_file, kConstructors[i]);
        },
        "must not be abstract or native");
    // Constructor without code marked abstract.
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_constructor_abstract_nocode",
        [&](DexFile* dex_file) {
          MakeDexVersion37(dex_file);
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kConstructors[i], kAccAbstract);
          RemoveCode(dex_file, kConstructors[i]);
        },
        "must not be abstract or native");
  }
  // <init> may only have (modulo ignored):
  // kAccPrivate | kAccProtected | kAccPublic | kAccStrict | kAccVarargs | kAccSynthetic
  static constexpr uint32_t kInitAllowed[] = {
      0,
      kAccPrivate,
      kAccProtected,
      kAccPublic,
      kAccStrict,
      kAccVarargs,
      kAccSynthetic
  };
  for (size_t i = 0; i < arraysize(kInitAllowed); ++i) {
    VerifyModification(
        kMethodFlagsTestDex,
        "init_allowed_flags",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
          OrMaskToMethodFlags(dex_file, "<init>", kInitAllowed[i]);
        },
        nullptr);
  }
  // Only one of public-private-protected.
  for (size_t i = 1; i < 8; ++i) {
    if (POPCOUNT(i) < 2) {
      continue;
    }
    // Technically the flags match, but just be defensive here.
    uint32_t mask = ((i & 1) != 0 ? kAccPrivate : 0) |
                    ((i & 2) != 0 ? kAccProtected : 0) |
                    ((i & 4) != 0 ? kAccPublic : 0);
    VerifyModification(
        kMethodFlagsTestDex,
        "init_one_of_ppp",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
          OrMaskToMethodFlags(dex_file, "<init>", mask);
        },
        "Method may have only one of public/protected/private");
  }
  // <init> doesn't allow
  // kAccStatic | kAccFinal | kAccSynchronized | kAccBridge
  // Need to handle static separately as it has its own error message.
  VerifyModification(
      kMethodFlagsTestDex,
      "init_not_allowed_flags",
      [&](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
        ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
        OrMaskToMethodFlags(dex_file, "<init>", kAccStatic);
      },
      "Constructor 1(LMethodFlags;.<init>) is not flagged correctly wrt/ static");
  static constexpr uint32_t kInitNotAllowed[] = {
      kAccFinal,
      kAccSynchronized,
      kAccBridge
  };
  for (size_t i = 0; i < arraysize(kInitNotAllowed); ++i) {
    VerifyModification(
        kMethodFlagsTestDex,
        "init_not_allowed_flags",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          ApplyMaskToMethodFlags(dex_file, "<init>", ~kAccPublic);
          OrMaskToMethodFlags(dex_file, "<init>", kInitNotAllowed[i]);
        },
        "Constructor 1(LMethodFlags;.<init>) flagged inappropriately");
  }
}

TEST_F(DexFileVerifierTest, MethodAccessFlagsMethods) {
  constexpr const char* kMethods[] = { "foo", "bar"};
  for (size_t i = 0; i < arraysize(kMethods); ++i) {
    // Make sure we reject non-constructors marked as constructors.
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_non_constructor",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kMethods[i], kAccConstructor);
        },
        "is marked constructor, but doesn't match name");

    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_native_with_code",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kMethods[i], kAccNative);
        },
        "has code, but is marked native or abstract");

    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_abstract_with_code",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract);
        },
        "has code, but is marked native or abstract");

    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_non_abstract_native_no_code",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          RemoveCode(dex_file, kMethods[i]);
        },
        "has no code, but is not marked native or abstract");

    // Abstract methods may not have the following flags.
    constexpr uint32_t kAbstractDisallowed[] = {
        kAccPrivate,
        kAccStatic,
        kAccFinal,
        kAccNative,
        kAccStrict,
        kAccSynchronized,
    };
    for (size_t j = 0; j < arraysize(kAbstractDisallowed); ++j) {
      VerifyModification(
          kMethodFlagsTestDex,
          "method_flags_abstract_and_disallowed_no_code",
          [&](DexFile* dex_file) {
            ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
            ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

            RemoveCode(dex_file, kMethods[i]);

            // Can't check private and static with foo, as it's in the virtual list and gives a
            // different error.
            if (((GetMethodFlags(dex_file, kMethods[i]) & kAccPublic) != 0) &&
                ((kAbstractDisallowed[j] & (kAccPrivate | kAccStatic)) != 0)) {
              // Use another breaking flag.
              OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAccFinal);
            } else {
              OrMaskToMethodFlags(dex_file, kMethods[i], kAccAbstract | kAbstractDisallowed[j]);
            }
          },
          "has disallowed access flags");
    }

    // Only one of public-private-protected.
    for (size_t j = 1; j < 8; ++j) {
      if (POPCOUNT(j) < 2) {
        continue;
      }
      // Technically the flags match, but just be defensive here.
      uint32_t mask = ((j & 1) != 0 ? kAccPrivate : 0) |
                      ((j & 2) != 0 ? kAccProtected : 0) |
                      ((j & 4) != 0 ? kAccPublic : 0);
      VerifyModification(
          kMethodFlagsTestDex,
          "method_flags_one_of_ppp",
          [&](DexFile* dex_file) {
            ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
            ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

            ApplyMaskToMethodFlags(dex_file, kMethods[i], ~kAccPublic);
            OrMaskToMethodFlags(dex_file, kMethods[i], mask);
          },
          "Method may have only one of public/protected/private");
    }
  }
}

TEST_F(DexFileVerifierTest, MethodAccessFlagsIgnoredOK) {
  constexpr const char* kMethods[] = { "<clinit>", "<init>", "foo", "bar"};
  for (size_t i = 0; i < arraysize(kMethods); ++i) {
    // All interesting method flags, other flags are to be ignored.
    constexpr uint32_t kAllMethodFlags =
        kAccPublic |
        kAccPrivate |
        kAccProtected |
        kAccStatic |
        kAccFinal |
        kAccSynchronized |
        kAccBridge |
        kAccVarargs |
        kAccNative |
        kAccAbstract |
        kAccStrict |
        kAccSynthetic;
    constexpr uint32_t kIgnoredMask = ~kAllMethodFlags & 0xFFFF;
    VerifyModification(
        kMethodFlagsTestDex,
        "method_flags_ignored",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToMethodFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToMethodFlags(dex_file, kMethods[i], kIgnoredMask);
        },
        nullptr);
  }
}

TEST_F(DexFileVerifierTest, B28552165) {
  // Regression test for bad error string retrieval in different situations.
  // Using invalid access flags to trigger the error.
  VerifyModification(
      kMethodFlagsTestDex,
      "b28552165",
      [](DexFile* dex_file) {
        OrMaskToMethodFlags(dex_file, "foo", kAccPublic | kAccProtected);
        uint32_t method_idx;
        FindMethodData(dex_file, "foo", &method_idx);
        auto* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(method_idx));
        method_id->name_idx_ = dex::StringIndex(dex_file->NumStringIds());
      },
      "Method may have only one of public/protected/private, LMethodFlags;.(error)");
}

// Set of dex files for interface method tests. As it's not as easy to mutate method names, it's
// just easier to break up bad cases.

// Standard interface. Use declared-synchronized again for 3B encoding.
//
// .class public interface LInterfaceMethodFlags;
// .super Ljava/lang/Object;
//
// .method public static constructor <clinit>()V
// .registers 1
//     return-void
// .end method
//
// .method public abstract declared-synchronized foo()V
// .end method
static const char kMethodFlagsInterface[] =
    "ZGV4CjAzNQCOM0odZ5bws1d9GSmumXaK5iE/7XxFpOm8AQAAcAAAAHhWNBIAAAAAAAAAADQBAAAF"
    "AAAAcAAAAAMAAACEAAAAAQAAAJAAAAAAAAAAAAAAAAIAAACcAAAAAQAAAKwAAADwAAAAzAAAAMwA"
    "AADWAAAA7gAAAAIBAAAFAQAAAQAAAAIAAAADAAAAAwAAAAIAAAAAAAAAAAAAAAAAAAAAAAAABAAA"
    "AAAAAAABAgAAAQAAAAAAAAD/////AAAAACIBAAAAAAAACDxjbGluaXQ+ABZMSW50ZXJmYWNlTWV0"
    "aG9kRmxhZ3M7ABJMamF2YS9sYW5nL09iamVjdDsAAVYAA2ZvbwAAAAAAAAABAAAAAAAAAAAAAAAB"
    "AAAADgAAAAEBAImABJACAYGICAAAAAALAAAAAAAAAAEAAAAAAAAAAQAAAAUAAABwAAAAAgAAAAMA"
    "AACEAAAAAwAAAAEAAACQAAAABQAAAAIAAACcAAAABgAAAAEAAACsAAAAAiAAAAUAAADMAAAAAxAA"
    "AAEAAAAMAQAAASAAAAEAAAAQAQAAACAAAAEAAAAiAQAAABAAAAEAAAA0AQAA";

// To simplify generation of interesting "sub-states" of src_value, allow a "simple" mask to apply
// to a src_value, such that mask bit 0 applies to the lowest set bit in src_value, and so on.
static uint32_t ApplyMaskShifted(uint32_t src_value, uint32_t mask) {
  uint32_t result = 0;
  uint32_t mask_index = 0;
  while (src_value != 0) {
    uint32_t index = CTZ(src_value);
    if (((src_value & (1 << index)) != 0) &&
        ((mask & (1 << mask_index)) != 0)) {
      result |= (1 << index);
    }
    src_value &= ~(1 << index);
    mask_index++;
  }
  return result;
}

TEST_F(DexFileVerifierTest, MethodAccessFlagsInterfaces) {
  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_ok",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
      },
      nullptr);
  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_ok37",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
      },
      nullptr);

  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_non_public",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_non_public",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
      },
      "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");

  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_non_abstract",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccAbstract);
      },
      "Method 1(LInterfaceMethodFlags;.foo) has no code, but is not marked native or abstract");

  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_static",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        OrMaskToMethodFlags(dex_file, "foo", kAccStatic);
      },
      "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");
  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_private",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToMethodFlags(dex_file, "foo", kAccPrivate);
      },
      "Direct/virtual method 1(LInterfaceMethodFlags;.foo) not in expected list 0");

  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_non_public",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_non_public",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
      },
      "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");

  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_protected",
      [](DexFile* dex_file) {
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kMethodFlagsInterface,
      "method_flags_interface_protected",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToMethodFlags(dex_file, "foo", kAccProtected);
      },
      "Interface virtual method 1(LInterfaceMethodFlags;.foo) is not public");

  constexpr uint32_t kAllMethodFlags =
      kAccPublic |
      kAccPrivate |
      kAccProtected |
      kAccStatic |
      kAccFinal |
      kAccSynchronized |
      kAccBridge |
      kAccVarargs |
      kAccNative |
      kAccAbstract |
      kAccStrict |
      kAccSynthetic;
  constexpr uint32_t kInterfaceMethodFlags =
      kAccPublic | kAccAbstract | kAccVarargs | kAccBridge | kAccSynthetic;
  constexpr uint32_t kInterfaceDisallowed = kAllMethodFlags &
                                            ~kInterfaceMethodFlags &
                                            // Already tested, needed to be separate.
                                            ~kAccStatic &
                                            ~kAccPrivate &
                                            ~kAccProtected;
  static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");

  uint32_t bits = POPCOUNT(kInterfaceDisallowed);
  for (uint32_t i = 1; i < (1u << bits); ++i) {
    VerifyModification(
        kMethodFlagsInterface,
        "method_flags_interface_non_abstract",
        [&](DexFile* dex_file) {
          ApplyMaskToMethodFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

          uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
          if ((mask & kAccProtected) != 0) {
            mask &= ~kAccProtected;
            ApplyMaskToMethodFlags(dex_file, "foo", ~kAccPublic);
          }
          OrMaskToMethodFlags(dex_file, "foo", mask);
        },
        "Abstract method 1(LInterfaceMethodFlags;.foo) has disallowed access flags");
  }
}

///////////////////////////////////////////////////////////////////

// Field flags.

// Find the method data for the first method with the given name (from class 0). Note: the pointer
// is to the access flags, so that the caller doesn't have to handle the leb128-encoded method-index
// delta.
static const uint8_t* FindFieldData(const DexFile* dex_file, const char* name) {
  const DexFile::ClassDef& class_def = dex_file->GetClassDef(0);
  const uint8_t* class_data = dex_file->GetClassData(class_def);

  ClassDataItemIterator it(*dex_file, class_data);

  const uint8_t* trailing = class_data;
  // Need to manually decode the four entries. DataPointer() doesn't work for this, as the first
  // element has already been loaded into the iterator.
  DecodeUnsignedLeb128(&trailing);
  DecodeUnsignedLeb128(&trailing);
  DecodeUnsignedLeb128(&trailing);
  DecodeUnsignedLeb128(&trailing);

  while (it.HasNextStaticField() || it.HasNextInstanceField()) {
    uint32_t field_index = it.GetMemberIndex();
    dex::StringIndex name_index = dex_file->GetFieldId(field_index).name_idx_;
    const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
    const char* str = dex_file->GetStringData(string_id);
    if (strcmp(name, str) == 0) {
      DecodeUnsignedLeb128(&trailing);
      return trailing;
    }

    trailing = it.DataPointer();
    it.Next();
  }

  return nullptr;
}

// Set the method flags to the given value.
static void SetFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
  uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
  CHECK(field_flags_ptr != nullptr) << field;

    // Unroll this, as we only have three bytes, anyways.
  uint8_t base1 = static_cast<uint8_t>(mask & 0x7F);
  *(field_flags_ptr++) = (base1 | 0x80);
  mask >>= 7;

  uint8_t base2 = static_cast<uint8_t>(mask & 0x7F);
  *(field_flags_ptr++) = (base2 | 0x80);
  mask >>= 7;

  uint8_t base3 = static_cast<uint8_t>(mask & 0x7F);
  *field_flags_ptr = base3;
}

static uint32_t GetFieldFlags(DexFile* dex_file, const char* field) {
  const uint8_t* field_flags_ptr = const_cast<uint8_t*>(FindFieldData(dex_file, field));
  CHECK(field_flags_ptr != nullptr) << field;
  return DecodeUnsignedLeb128(&field_flags_ptr);
}

// Apply the given mask to method flags.
static void ApplyMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
  uint32_t value = GetFieldFlags(dex_file, field);
  value &= mask;
  SetFieldFlags(dex_file, field, value);
}

// Apply the given mask to method flags.
static void OrMaskToFieldFlags(DexFile* dex_file, const char* field, uint32_t mask) {
  uint32_t value = GetFieldFlags(dex_file, field);
  value |= mask;
  SetFieldFlags(dex_file, field, value);
}

// Standard class. Use declared-synchronized again for 3B encoding.
//
// .class public LFieldFlags;
// .super Ljava/lang/Object;
//
// .field declared-synchronized public foo:I
//
// .field declared-synchronized public static bar:I

static const char kFieldFlagsTestDex[] =
    "ZGV4CjAzNQBtLw7hydbfv4TdXidZyzAB70W7w3vnYJRwAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAF"
    "AAAAcAAAAAMAAACEAAAAAAAAAAAAAAACAAAAkAAAAAAAAAAAAAAAAQAAAKAAAACwAAAAwAAAAMAA"
    "AADDAAAA0QAAAOUAAADqAAAAAAAAAAEAAAACAAAAAQAAAAMAAAABAAAABAAAAAEAAAABAAAAAgAA"
    "AAAAAAD/////AAAAAPQAAAAAAAAAAUkADExGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7"
    "AANiYXIAA2ZvbwAAAAAAAAEBAAAAiYAIAYGACAkAAAAAAAAAAQAAAAAAAAABAAAABQAAAHAAAAAC"
    "AAAAAwAAAIQAAAAEAAAAAgAAAJAAAAAGAAAAAQAAAKAAAAACIAAABQAAAMAAAAADEAAAAQAAAPAA"
    "AAAAIAAAAQAAAPQAAAAAEAAAAQAAAAABAAA=";

TEST_F(DexFileVerifierTest, FieldAccessFlagsBase) {
  // Check that it's OK when the wrong declared-synchronized flag is removed from "foo."
  VerifyModification(
      kFieldFlagsTestDex,
      "field_flags_ok",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
        ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);
      },
      nullptr);
}

TEST_F(DexFileVerifierTest, FieldAccessFlagsWrongList) {
  // Mark the field so that it should appear in the opposite list (instance vs static).
  VerifyModification(
      kFieldFlagsTestDex,
      "field_flags_wrong_list",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
        ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

        OrMaskToFieldFlags(dex_file, "foo", kAccStatic);
      },
      "Static/instance field not in expected list");
  VerifyModification(
      kFieldFlagsTestDex,
      "field_flags_wrong_list",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
        ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "bar", ~kAccStatic);
      },
      "Static/instance field not in expected list");
}

TEST_F(DexFileVerifierTest, FieldAccessFlagsPPP) {
  static const char* kFields[] = { "foo", "bar" };
  for (size_t i = 0; i < arraysize(kFields); ++i) {
    // Should be OK to remove public.
    VerifyModification(
        kFieldFlagsTestDex,
        "field_flags_non_public",
        [&](DexFile* dex_file) {
          ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
        },
        nullptr);
    constexpr uint32_t kAccFlags = kAccPublic | kAccPrivate | kAccProtected;
    uint32_t bits = POPCOUNT(kAccFlags);
    for (uint32_t j = 1; j < (1u << bits); ++j) {
      if (POPCOUNT(j) < 2) {
        continue;
      }
      VerifyModification(
           kFieldFlagsTestDex,
           "field_flags_ppp",
           [&](DexFile* dex_file) {
             ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
             ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

             ApplyMaskToFieldFlags(dex_file, kFields[i], ~kAccPublic);
             uint32_t mask = ApplyMaskShifted(kAccFlags, j);
             OrMaskToFieldFlags(dex_file, kFields[i], mask);
           },
           "Field may have only one of public/protected/private");
    }
  }
}

TEST_F(DexFileVerifierTest, FieldAccessFlagsIgnoredOK) {
  constexpr const char* kFields[] = { "foo", "bar"};
  for (size_t i = 0; i < arraysize(kFields); ++i) {
    // All interesting method flags, other flags are to be ignored.
    constexpr uint32_t kAllFieldFlags =
        kAccPublic |
        kAccPrivate |
        kAccProtected |
        kAccStatic |
        kAccFinal |
        kAccVolatile |
        kAccTransient |
        kAccSynthetic |
        kAccEnum;
    constexpr uint32_t kIgnoredMask = ~kAllFieldFlags & 0xFFFF;
    VerifyModification(
        kFieldFlagsTestDex,
        "field_flags_ignored",
        [&](DexFile* dex_file) {
          ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToFieldFlags(dex_file, kFields[i], kIgnoredMask);
        },
        nullptr);
  }
}

TEST_F(DexFileVerifierTest, FieldAccessFlagsVolatileFinal) {
  constexpr const char* kFields[] = { "foo", "bar"};
  for (size_t i = 0; i < arraysize(kFields); ++i) {
    VerifyModification(
        kFieldFlagsTestDex,
        "field_flags_final_and_volatile",
        [&](DexFile* dex_file) {
          ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
          ApplyMaskToFieldFlags(dex_file, "bar", ~kAccDeclaredSynchronized);

          OrMaskToFieldFlags(dex_file, kFields[i], kAccVolatile | kAccFinal);
        },
        "Fields may not be volatile and final");
  }
}

// Standard interface. Needs to be separate from class as interfaces do not allow instance fields.
// Use declared-synchronized again for 3B encoding.
//
// .class public interface LInterfaceFieldFlags;
// .super Ljava/lang/Object;
//
// .field declared-synchronized public static final foo:I

static const char kFieldFlagsInterfaceTestDex[] =
    "ZGV4CjAzNQCVMHfEimR1zZPk6hl6O9GPAYqkl3u0umFkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
    "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
    "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
    "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
    "b28AAAAAAAABAAAAAJmACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
    "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
    "AAAAEAAAAQAAAPQAAAA=";

TEST_F(DexFileVerifierTest, FieldAccessFlagsInterface) {
  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
      },
      nullptr);
  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
      },
      nullptr);

  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_non_public",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_non_public",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
      },
      "Interface field is not public final static");

  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_non_final",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_non_final",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccFinal);
      },
      "Interface field is not public final static");

  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_protected",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_protected",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToFieldFlags(dex_file, "foo", kAccProtected);
      },
      "Interface field is not public final static");

  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_private",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_private",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
        OrMaskToFieldFlags(dex_file, "foo", kAccPrivate);
      },
      "Interface field is not public final static");

  VerifyModification(
      kFieldFlagsInterfaceTestDex,
      "field_flags_interface_synthetic",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

        OrMaskToFieldFlags(dex_file, "foo", kAccSynthetic);
      },
      nullptr);

  constexpr uint32_t kAllFieldFlags =
      kAccPublic |
      kAccPrivate |
      kAccProtected |
      kAccStatic |
      kAccFinal |
      kAccVolatile |
      kAccTransient |
      kAccSynthetic |
      kAccEnum;
  constexpr uint32_t kInterfaceFieldFlags = kAccPublic | kAccStatic | kAccFinal | kAccSynthetic;
  constexpr uint32_t kInterfaceDisallowed = kAllFieldFlags &
                                            ~kInterfaceFieldFlags &
                                            ~kAccProtected &
                                            ~kAccPrivate;
  static_assert(kInterfaceDisallowed != 0, "There should be disallowed flags.");

  uint32_t bits = POPCOUNT(kInterfaceDisallowed);
  for (uint32_t i = 1; i < (1u << bits); ++i) {
    VerifyModification(
        kFieldFlagsInterfaceTestDex,
        "field_flags_interface_disallowed",
        [&](DexFile* dex_file) {
          ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

          uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
          if ((mask & kAccProtected) != 0) {
            mask &= ~kAccProtected;
            ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
          }
          OrMaskToFieldFlags(dex_file, "foo", mask);
        },
        nullptr);  // Should be allowed in older dex versions for backwards compatibility.
    VerifyModification(
        kFieldFlagsInterfaceTestDex,
        "field_flags_interface_disallowed",
        [&](DexFile* dex_file) {
          MakeDexVersion37(dex_file);
          ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);

          uint32_t mask = ApplyMaskShifted(kInterfaceDisallowed, i);
          if ((mask & kAccProtected) != 0) {
            mask &= ~kAccProtected;
            ApplyMaskToFieldFlags(dex_file, "foo", ~kAccPublic);
          }
          OrMaskToFieldFlags(dex_file, "foo", mask);
        },
        "Interface field has disallowed flag");
  }
}

// Standard bad interface. Needs to be separate from class as interfaces do not allow instance
// fields. Use declared-synchronized again for 3B encoding.
//
// .class public interface LInterfaceFieldFlags;
// .super Ljava/lang/Object;
//
// .field declared-synchronized public final foo:I

static const char kFieldFlagsInterfaceBadTestDex[] =
    "ZGV4CjAzNQByMUnqYKHBkUpvvNp+9CnZ2VyDkKnRN6VkAQAAcAAAAHhWNBIAAAAAAAAAAPQAAAAE"
    "AAAAcAAAAAMAAACAAAAAAAAAAAAAAAABAAAAjAAAAAAAAAAAAAAAAQAAAJQAAACwAAAAtAAAALQA"
    "AAC3AAAAzgAAAOIAAAAAAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAgAAAgAAAAAAAAD/////AAAA"
    "AOwAAAAAAAAAAUkAFUxJbnRlcmZhY2VGaWVsZEZsYWdzOwASTGphdmEvbGFuZy9PYmplY3Q7AANm"
    "b28AAAAAAAAAAQAAAJGACAkAAAAAAAAAAQAAAAAAAAABAAAABAAAAHAAAAACAAAAAwAAAIAAAAAE"
    "AAAAAQAAAIwAAAAGAAAAAQAAAJQAAAACIAAABAAAALQAAAADEAAAAQAAAOgAAAAAIAAAAQAAAOwA"
    "AAAAEAAAAQAAAPQAAAA=";

TEST_F(DexFileVerifierTest, FieldAccessFlagsInterfaceNonStatic) {
  VerifyModification(
      kFieldFlagsInterfaceBadTestDex,
      "field_flags_interface_non_static",
      [](DexFile* dex_file) {
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
      },
      nullptr);  // Should be allowed in older dex versions for backwards compatibility.
  VerifyModification(
      kFieldFlagsInterfaceBadTestDex,
      "field_flags_interface_non_static",
      [](DexFile* dex_file) {
        MakeDexVersion37(dex_file);
        ApplyMaskToFieldFlags(dex_file, "foo", ~kAccDeclaredSynchronized);
      },
      "Interface field is not public final static");
}

// Generated from:
//
// .class public LTest;
// .super Ljava/lang/Object;
// .source "Test.java"
//
// .method public constructor <init>()V
//     .registers 1
//
//     .prologue
//     .line 1
//     invoke-direct {p0}, Ljava/lang/Object;-><init>()V
//
//     return-void
// .end method
//
// .method public static main()V
//     .registers 2
//
//     const-string v0, "a"
//     const-string v0, "b"
//     const-string v0, "c"
//     const-string v0, "d"
//     const-string v0, "e"
//     const-string v0, "f"
//     const-string v0, "g"
//     const-string v0, "h"
//     const-string v0, "i"
//     const-string v0, "j"
//     const-string v0, "k"
//
//     .local v1, "local_var":Ljava/lang/String;
//     const-string v1, "test"
// .end method

static const char kDebugInfoTestDex[] =
    "ZGV4CjAzNQCHRkHix2eIMQgvLD/0VGrlllZLo0Rb6VyUAgAAcAAAAHhWNBIAAAAAAAAAAAwCAAAU"
    "AAAAcAAAAAQAAADAAAAAAQAAANAAAAAAAAAAAAAAAAMAAADcAAAAAQAAAPQAAACAAQAAFAEAABQB"
    "AAAcAQAAJAEAADgBAABMAQAAVwEAAFoBAABdAQAAYAEAAGMBAABmAQAAaQEAAGwBAABvAQAAcgEA"
    "AHUBAAB4AQAAewEAAIYBAACMAQAAAQAAAAIAAAADAAAABQAAAAUAAAADAAAAAAAAAAAAAAAAAAAA"
    "AAAAABIAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAEAAAAAAAAAPwBAAAAAAAABjxpbml0PgAG"
    "TFRlc3Q7ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3RyaW5nOwAJVGVzdC5qYXZh"
    "AAFWAAFhAAFiAAFjAAFkAAFlAAFmAAFnAAFoAAFpAAFqAAFrAAlsb2NhbF92YXIABG1haW4ABHRl"
    "c3QAAAABAAcOAAAAARYDARIDAAAAAQABAAEAAACUAQAABAAAAHAQAgAAAA4AAgAAAAAAAACZAQAA"
    "GAAAABoABgAaAAcAGgAIABoACQAaAAoAGgALABoADAAaAA0AGgAOABoADwAaABAAGgETAAAAAgAA"
    "gYAEpAMBCbwDAAALAAAAAAAAAAEAAAAAAAAAAQAAABQAAABwAAAAAgAAAAQAAADAAAAAAwAAAAEA"
    "AADQAAAABQAAAAMAAADcAAAABgAAAAEAAAD0AAAAAiAAABQAAAAUAQAAAyAAAAIAAACUAQAAASAA"
    "AAIAAACkAQAAACAAAAEAAAD8AQAAABAAAAEAAAAMAgAA";

TEST_F(DexFileVerifierTest, DebugInfoTypeIdxTest) {
  {
    // The input dex file should be good before modification.
    ScratchFile tmp;
    std::string error_msg;
    std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kDebugInfoTestDex,
                                                         tmp.GetFilename().c_str(),
                                                         &error_msg));
    ASSERT_TRUE(raw.get() != nullptr) << error_msg;
  }

  // Modify the debug information entry.
  VerifyModification(
      kDebugInfoTestDex,
      "debug_start_type_idx",
      [](DexFile* dex_file) {
        *(const_cast<uint8_t*>(dex_file->Begin()) + 416) = 0x14U;
      },
      "DBG_START_LOCAL type_idx");
}

TEST_F(DexFileVerifierTest, SectionAlignment) {
  {
    // The input dex file should be good before modification. Any file is fine, as long as it
    // uses all sections.
    ScratchFile tmp;
    std::string error_msg;
    std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kGoodTestDex,
                                                         tmp.GetFilename().c_str(),
                                                         &error_msg));
    ASSERT_TRUE(raw.get() != nullptr) << error_msg;
  }

  // Modify all section offsets to be unaligned.
  constexpr size_t kSections = 7;
  for (size_t i = 0; i < kSections; ++i) {
    VerifyModification(
        kGoodTestDex,
        "section_align",
        [&](DexFile* dex_file) {
          DexFile::Header* header = const_cast<DexFile::Header*>(
              reinterpret_cast<const DexFile::Header*>(dex_file->Begin()));
          uint32_t* off_ptr;
          switch (i) {
            case 0:
              off_ptr = &header->map_off_;
              break;
            case 1:
              off_ptr = &header->string_ids_off_;
              break;
            case 2:
              off_ptr = &header->type_ids_off_;
              break;
            case 3:
              off_ptr = &header->proto_ids_off_;
              break;
            case 4:
              off_ptr = &header->field_ids_off_;
              break;
            case 5:
              off_ptr = &header->method_ids_off_;
              break;
            case 6:
              off_ptr = &header->class_defs_off_;
              break;

            static_assert(kSections == 7, "kSections is wrong");
            default:
              LOG(FATAL) << "Unexpected section";
              UNREACHABLE();
          }
          ASSERT_TRUE(off_ptr != nullptr);
          ASSERT_NE(*off_ptr, 0U) << i;  // Should already contain a value (in use).
          (*off_ptr)++;                  // Add one, which should misalign it (all the sections
                                         // above are aligned by 4).
        },
        "should be aligned by 4 for");
  }
}

// Generated from
//
// .class LOverloading;
//
// .super Ljava/lang/Object;
//
// .method public static foo()V
// .registers 1
//     return-void
// .end method
//
// .method public static foo(I)V
// .registers 1
//     return-void
// .end method
static const char kProtoOrderingTestDex[] =
    "ZGV4CjAzNQA1L+ABE6voQ9Lr4Ci//efB53oGnDr5PinsAQAAcAAAAHhWNBIAAAAAAAAAAFgBAAAG"
    "AAAAcAAAAAQAAACIAAAAAgAAAJgAAAAAAAAAAAAAAAIAAACwAAAAAQAAAMAAAAAMAQAA4AAAAOAA"
    "AADjAAAA8gAAAAYBAAAJAQAADQEAAAAAAAABAAAAAgAAAAMAAAADAAAAAwAAAAAAAAAEAAAAAwAA"
    "ABQBAAABAAAABQAAAAEAAQAFAAAAAQAAAAAAAAACAAAAAAAAAP////8AAAAASgEAAAAAAAABSQAN"
    "TE92ZXJsb2FkaW5nOwASTGphdmEvbGFuZy9PYmplY3Q7AAFWAAJWSQADZm9vAAAAAQAAAAAAAAAA"
    "AAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAOAAAAAQABAAAAAAAAAAAAAQAAAA4AAAACAAAJpAIBCbgC"
    "AAAMAAAAAAAAAAEAAAAAAAAAAQAAAAYAAABwAAAAAgAAAAQAAACIAAAAAwAAAAIAAACYAAAABQAA"
    "AAIAAACwAAAABgAAAAEAAADAAAAAAiAAAAYAAADgAAAAARAAAAEAAAAUAQAAAxAAAAIAAAAcAQAA"
    "ASAAAAIAAAAkAQAAACAAAAEAAABKAQAAABAAAAEAAABYAQAA";

TEST_F(DexFileVerifierTest, ProtoOrdering) {
  {
    // The input dex file should be good before modification.
    ScratchFile tmp;
    std::string error_msg;
    std::unique_ptr<const DexFile> raw(OpenDexFileBase64(kProtoOrderingTestDex,
                                                         tmp.GetFilename().c_str(),
                                                         &error_msg));
    ASSERT_TRUE(raw.get() != nullptr) << error_msg;
  }

  // Modify the order of the ProtoIds for two overloads of "foo" with the
  // same return type and one having longer parameter list than the other.
  for (size_t i = 0; i != 2; ++i) {
    VerifyModification(
        kProtoOrderingTestDex,
        "proto_ordering",
        [i](DexFile* dex_file) {
          uint32_t method_idx;
          const uint8_t* data = FindMethodData(dex_file, "foo", &method_idx);
          CHECK(data != nullptr);
          // There should be 2 methods called "foo".
          CHECK_LT(method_idx + 1u, dex_file->NumMethodIds());
          CHECK_EQ(dex_file->GetMethodId(method_idx).name_idx_,
                   dex_file->GetMethodId(method_idx + 1).name_idx_);
          CHECK_EQ(dex_file->GetMethodId(method_idx).proto_idx_ + 1u,
                   dex_file->GetMethodId(method_idx + 1).proto_idx_);
          // Their return types should be the same.
          uint32_t proto1_idx = dex_file->GetMethodId(method_idx).proto_idx_;
          const DexFile::ProtoId& proto1 = dex_file->GetProtoId(proto1_idx);
          const DexFile::ProtoId& proto2 = dex_file->GetProtoId(proto1_idx + 1u);
          CHECK_EQ(proto1.return_type_idx_, proto2.return_type_idx_);
          // And the first should not have any parameters while the second should have some.
          CHECK(!DexFileParameterIterator(*dex_file, proto1).HasNext());
          CHECK(DexFileParameterIterator(*dex_file, proto2).HasNext());
          if (i == 0) {
            // Swap the proto parameters and shorties to break the ordering.
            std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
                      const_cast<uint32_t&>(proto2.parameters_off_));
            std::swap(const_cast<dex::StringIndex&>(proto1.shorty_idx_),
                      const_cast<dex::StringIndex&>(proto2.shorty_idx_));
          } else {
            // Copy the proto parameters and shorty to create duplicate proto id.
            const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
            const_cast<dex::StringIndex&>(proto1.shorty_idx_) = proto2.shorty_idx_;
          }
        },
        "Out-of-order proto_id arguments");
  }
}

// To generate a base64 encoded Dex file version 037 from Smali files, use:
//
//   smali --api-level 24 -o classes.dex class1.smali [class2.smali ...]
//   base64 classes.dex >classes.dex.base64

// Dex file version 037 generated from:
//
//   .class public LB28685551;
//   .super LB28685551;

static const char kClassExtendsItselfTestDex[] =
    "ZGV4CjAzNwDeGbgRg1kb6swszpcTWrrOAALB++F4OPT0AAAAcAAAAHhWNBIAAAAAAAAAAKgAAAAB"
    "AAAAcAAAAAEAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAHgAAABcAAAAmAAAAJgA"
    "AAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAALTEIyODY4NTU1MTsAAAAABgAA"
    "AAAAAAABAAAAAAAAAAEAAAABAAAAcAAAAAIAAAABAAAAdAAAAAYAAAABAAAAeAAAAAIgAAABAAAA"
    "mAAAAAAQAAABAAAAqAAAAA==";

TEST_F(DexFileVerifierTest, ClassExtendsItself) {
  VerifyModification(
      kClassExtendsItselfTestDex,
      "class_extends_itself",
      [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
      "Class with same type idx as its superclass: '0'");
}

// Dex file version 037 generated from:
//
//   .class public LFoo;
//   .super LBar;
//
// and:
//
//    .class public LBar;
//    .super LFoo;

static const char kClassesExtendOneAnotherTestDex[] =
    "ZGV4CjAzNwBXHSrwpDMwRBkg+L+JeQCuFNRLhQ86duEcAQAAcAAAAHhWNBIAAAAAAAAAANAAAAAC"
    "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIAAAABcAAAAwAAAAMAA"
    "AADHAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAAAAAAABAAAAAQAA"
    "AAAAAAD/////AAAAAAAAAAAAAAAABUxCYXI7AAVMRm9vOwAAAAYAAAAAAAAAAQAAAAAAAAABAAAA"
    "AgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAgAAAIAAAAACIAAAAgAAAMAAAAAAEAAAAQAAANAAAAA=";

TEST_F(DexFileVerifierTest, ClassesExtendOneAnother) {
  VerifyModification(
      kClassesExtendOneAnotherTestDex,
      "classes_extend_one_another",
      [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
      "Invalid class definition ordering: class with type idx: '1' defined before"
      " superclass with type idx: '0'");
}

// Dex file version 037 generated from:
//
//   .class public LAll;
//   .super LYour;
//
// and:
//
//   .class public LYour;
//   .super LBase;
//
// and:
//
//   .class public LBase;
//   .super LAll;

static const char kCircularClassInheritanceTestDex[] =
    "ZGV4CjAzNwBMJxgP0SJz6oLXnKfl+J7lSEORLRwF5LNMAQAAcAAAAHhWNBIAAAAAAAAAAAABAAAD"
    "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAIgAAABkAAAA6AAAAOgA"
    "AADvAAAA9wAAAAAAAAABAAAAAgAAAAEAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAgAA"
    "AAEAAAABAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAAAAAAA/////wAAAAAAAAAA"
    "AAAAAAVMQWxsOwAGTEJhc2U7AAZMWW91cjsAAAYAAAAAAAAAAQAAAAAAAAABAAAAAwAAAHAAAAAC"
    "AAAAAwAAAHwAAAAGAAAAAwAAAIgAAAACIAAAAwAAAOgAAAAAEAAAAQAAAAABAAA=";

TEST_F(DexFileVerifierTest, CircularClassInheritance) {
  VerifyModification(
      kCircularClassInheritanceTestDex,
      "circular_class_inheritance",
      [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
      "Invalid class definition ordering: class with type idx: '1' defined before"
      " superclass with type idx: '0'");
}

// Dex file version 037 generated from:
//
//   .class public abstract interface LInterfaceImplementsItself;
//   .super Ljava/lang/Object;
//   .implements LInterfaceImplementsItself;

static const char kInterfaceImplementsItselfTestDex[] =
    "ZGV4CjAzNwCKKrjatp8XbXl5S/bEVJnqaBhjZkQY4440AQAAcAAAAHhWNBIAAAAAAAAAANwAAAAC"
    "AAAAcAAAAAIAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAIAAAACUAAAAoAAAAKAA"
    "AAC9AAAAAAAAAAEAAAAAAAAAAQYAAAEAAADUAAAA/////wAAAAAAAAAAAAAAABtMSW50ZXJmYWNl"
    "SW1wbGVtZW50c0l0c2VsZjsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAAABAAAAAAAAAAcAAAAAAAAA"
    "AQAAAAAAAAABAAAAAgAAAHAAAAACAAAAAgAAAHgAAAAGAAAAAQAAAIAAAAACIAAAAgAAAKAAAAAB"
    "EAAAAQAAANQAAAAAEAAAAQAAANwAAAA=";

TEST_F(DexFileVerifierTest, InterfaceImplementsItself) {
  VerifyModification(
      kInterfaceImplementsItselfTestDex,
      "interface_implements_itself",
      [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
      "Class with same type idx as implemented interface: '0'");
}

// Dex file version 037 generated from:
//
//   .class public abstract interface LPing;
//   .super Ljava/lang/Object;
//   .implements LPong;
//
// and:
//
//   .class public abstract interface LPong;
//   .super Ljava/lang/Object;
//   .implements LPing;

static const char kInterfacesImplementOneAnotherTestDex[] =
    "ZGV4CjAzNwD0Kk9sxlYdg3Dy1Cff0gQCuJAQfEP6ohZUAQAAcAAAAHhWNBIAAAAAAAAAAPwAAAAD"
    "AAAAcAAAAAMAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAIgAAACMAAAAyAAAAMgA"
    "AADQAAAA2AAAAAAAAAABAAAAAgAAAAEAAAABBgAAAgAAAOwAAAD/////AAAAAAAAAAAAAAAAAAAA"
    "AAEGAAACAAAA9AAAAP////8AAAAAAAAAAAAAAAAGTFBpbmc7AAZMUG9uZzsAEkxqYXZhL2xhbmcv"
    "T2JqZWN0OwABAAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAADAAAAcAAAAAIAAAAD"
    "AAAAfAAAAAYAAAACAAAAiAAAAAIgAAADAAAAyAAAAAEQAAACAAAA7AAAAAAQAAABAAAA/AAAAA==";

TEST_F(DexFileVerifierTest, InterfacesImplementOneAnother) {
  VerifyModification(
      kInterfacesImplementOneAnotherTestDex,
      "interfaces_implement_one_another",
      [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
      "Invalid class definition ordering: class with type idx: '1' defined before"
      " implemented interface with type idx: '0'");
}

// Dex file version 037 generated from:
//
//   .class public abstract interface LA;
//   .super Ljava/lang/Object;
//   .implements LB;
//
// and:
//
//   .class public abstract interface LB;
//   .super Ljava/lang/Object;
//   .implements LC;
//
// and:
//
//   .class public abstract interface LC;
//   .super Ljava/lang/Object;
//   .implements LA;

static const char kCircularInterfaceImplementationTestDex[] =
    "ZGV4CjAzNwCzKmD5Fol6XAU6ichYHcUTIP7Z7MdTcEmEAQAAcAAAAHhWNBIAAAAAAAAAACwBAAAE"
    "AAAAcAAAAAQAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAJAAAACUAAAA8AAAAPAA"
    "AAD1AAAA+gAAAP8AAAAAAAAAAQAAAAIAAAADAAAAAgAAAAEGAAADAAAAHAEAAP////8AAAAAAAAA"
    "AAAAAAABAAAAAQYAAAMAAAAUAQAA/////wAAAAAAAAAAAAAAAAAAAAABBgAAAwAAACQBAAD/////"
    "AAAAAAAAAAAAAAAAA0xBOwADTEI7AANMQzsAEkxqYXZhL2xhbmcvT2JqZWN0OwAAAQAAAAIAAAAB"
    "AAAAAAAAAAEAAAABAAAABwAAAAAAAAABAAAAAAAAAAEAAAAEAAAAcAAAAAIAAAAEAAAAgAAAAAYA"
    "AAADAAAAkAAAAAIgAAAEAAAA8AAAAAEQAAADAAAAFAEAAAAQAAABAAAALAEAAA==";

TEST_F(DexFileVerifierTest, CircularInterfaceImplementation) {
  VerifyModification(
      kCircularInterfaceImplementationTestDex,
      "circular_interface_implementation",
      [](DexFile* dex_file ATTRIBUTE_UNUSED) { /* empty */ },
      "Invalid class definition ordering: class with type idx: '2' defined before"
      " implemented interface with type idx: '0'");
}

TEST_F(DexFileVerifierTest, Checksum) {
  size_t length;
  std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kGoodTestDex, &length));
  CHECK(dex_bytes != nullptr);
  // Note: `dex_file` will be destroyed before `dex_bytes`.
  std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
  std::string error_msg;

  // Good checksum: all pass.
  EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
                                      dex_file->Begin(),
                                      dex_file->Size(),
                                       "good checksum, no verify",
                                      /*verify_checksum*/ false,
                                      &error_msg));
  EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
                                      dex_file->Begin(),
                                      dex_file->Size(),
                                      "good checksum, verify",
                                      /*verify_checksum*/ true,
                                      &error_msg));

  // Bad checksum: !verify_checksum passes verify_checksum fails.
  DexFile::Header* header = reinterpret_cast<DexFile::Header*>(
      const_cast<uint8_t*>(dex_file->Begin()));
  header->checksum_ = 0;
  EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
                                      dex_file->Begin(),
                                      dex_file->Size(),
                                      "bad checksum, no verify",
                                      /*verify_checksum*/ false,
                                      &error_msg));
  EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(),
                                       dex_file->Begin(),
                                       dex_file->Size(),
                                       "bad checksum, verify",
                                       /*verify_checksum*/ true,
                                       &error_msg));
  EXPECT_NE(error_msg.find("Bad checksum"), std::string::npos) << error_msg;
}

}  // namespace art
