/*
 * Copyright (C) 2020 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 "sdk_checker.h"

#include "art_method-inl.h"
#include "base/utils.h"
#include "dex/art_dex_file_loader.h"
#include "mirror/class-inl.h"

namespace art {

SdkChecker::SdkChecker() : enabled_(true) {}

SdkChecker* SdkChecker::Create(const std::string& public_sdk, std::string* error_msg) {
  std::vector<std::string> dex_file_paths;
  Split(public_sdk, ':', &dex_file_paths);

  std::unique_ptr<SdkChecker> sdk_checker(new SdkChecker());
  for (const std::string& path : dex_file_paths) {
    DexFileLoader dex_file_loader(path);
    if (!dex_file_loader.Open(/*verify=*/true,
                              /*verify_checksum*/ false,
                              error_msg,
                              &sdk_checker->sdk_dex_files_)) {
      return nullptr;
    }
  }
  return sdk_checker.release();
}

bool SdkChecker::ShouldDenyAccess(ArtMethod* art_method) const {
  if (!enabled_) {
    return false;
  }

  bool found = false;
  for (const std::unique_ptr<const DexFile>& dex_file : sdk_dex_files_) {
    const dex::TypeId* declaring_type_id =
        dex_file->FindTypeId(art_method->GetDeclaringClassDescriptor());
    if (declaring_type_id == nullptr) {
      continue;
    }
    const dex::StringId* name_id = dex_file->FindStringId(art_method->GetName());
    if (name_id == nullptr) {
      continue;
    }

    dex::TypeIndex return_type_idx;
    std::vector<dex::TypeIndex> param_type_idxs;
    if (!dex_file->CreateTypeList(
            art_method->GetSignature().ToString(), &return_type_idx, &param_type_idxs)) {
      continue;
    }
    const dex::ProtoId* proto_id = dex_file->FindProtoId(return_type_idx, param_type_idxs);
    if (proto_id == nullptr) {
      continue;
    }

    const dex::MethodId* method_id =
        dex_file->FindMethodId(*declaring_type_id, *name_id, *proto_id);
    if (method_id != nullptr) {
      found = true;
      break;
    }
  }

  if (!found) {
    VLOG(verifier) << "Deny for " << art_method->PrettyMethod(true);
  }

  // Deny access if we didn't find the descriptor in the public api dex files.
  return !found;
}

bool SdkChecker::ShouldDenyAccess(ArtField* art_field) const {
  if (!enabled_) {
    return false;
  }

  bool found = false;
  for (const std::unique_ptr<const DexFile>& dex_file : sdk_dex_files_) {
    std::string declaring_class;

    const dex::TypeId* declaring_type_id =
        dex_file->FindTypeId(art_field->GetDeclaringClass()->GetDescriptor(&declaring_class));
    if (declaring_type_id == nullptr) {
      continue;
    }
    const dex::StringId* name_id = dex_file->FindStringId(art_field->GetName());
    if (name_id == nullptr) {
      continue;
    }
    const dex::TypeId* type_id = dex_file->FindTypeId(art_field->GetTypeDescriptor());
    if (type_id == nullptr) {
      continue;
    }

    const dex::FieldId* field_id = dex_file->FindFieldId(*declaring_type_id, *name_id, *type_id);
    if (field_id != nullptr) {
      found = true;
      break;
    }
  }

  if (!found) {
    VLOG(verifier) << "Deny for " << ArtField::PrettyField(art_field, true);
  }

  // Deny access if we didn't find the descriptor in the public api dex files.
  return !found;
}

bool SdkChecker::ShouldDenyAccess(const char* descriptor) const {
  if (!enabled_) {
    return false;
  }

  bool found = false;
  for (const std::unique_ptr<const DexFile>& dex_file : sdk_dex_files_) {
    const dex::TypeId* type_id = dex_file->FindTypeId(descriptor);
    if (type_id != nullptr) {
      dex::TypeIndex type_idx = dex_file->GetIndexForTypeId(*type_id);
      if (dex_file->FindClassDef(type_idx) != nullptr) {
        found = true;
        break;
      }
    }
  }

  if (!found) {
    VLOG(verifier) << "Deny for " << descriptor;
  }

  // Deny access if we didn't find the descriptor in the public api dex files.
  return !found;
}

}  // namespace art
