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

#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_instruction-inl.h"
#include "dex/dex_file.h"
#include "dex/method_reference.h"
#include "hidden_api.h"
#include "resolver.h"
#include "veridex.h"

#include <iostream>

namespace art {

void HiddenApiFinder::CheckMethod(uint32_t method_id,
                                  VeridexResolver* resolver,
                                  MethodReference ref) {
  // Note: we always query whether a method is in a list, as the app
  // might define blacklisted APIs (which won't be used at runtime).
  std::string name = HiddenApi::GetApiMethodName(resolver->GetDexFile(), method_id);
  if (hidden_api_.IsInRestrictionList(name)) {
    method_locations_[name].push_back(ref);
  }
}

void HiddenApiFinder::CheckField(uint32_t field_id,
                                 VeridexResolver* resolver,
                                 MethodReference ref) {
  // Note: we always query whether a field is in a list, as the app
  // might define blacklisted APIs (which won't be used at runtime).
  std::string name = HiddenApi::GetApiFieldName(resolver->GetDexFile(), field_id);
  if (hidden_api_.IsInRestrictionList(name)) {
    field_locations_[name].push_back(ref);
  }
}

void HiddenApiFinder::CollectAccesses(VeridexResolver* resolver) {
  const DexFile& dex_file = resolver->GetDexFile();
  // Look at all types referenced in this dex file. Any of these
  // types can lead to being used through reflection.
  for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) {
    std::string name(dex_file.StringByTypeIdx(dex::TypeIndex(i)));
    if (hidden_api_.IsInRestrictionList(name)) {
      classes_.insert(name);
    }
  }
  // Note: we collect strings constants only referenced in code items as the string table
  // contains other kind of strings (eg types).
  for (ClassAccessor accessor : dex_file.GetClasses()) {
    for (const ClassAccessor::Method& method : accessor.GetMethods()) {
      for (const DexInstructionPcPair& inst : method.GetInstructions()) {
        switch (inst->Opcode()) {
          case Instruction::CONST_STRING: {
            dex::StringIndex string_index(inst->VRegB_21c());
            std::string name = std::string(dex_file.StringDataByIdx(string_index));
            // Cheap filtering on the string literal. We know it cannot be a field/method/class
            // if it contains a space.
            if (name.find(' ') == std::string::npos) {
              // Class names at the Java level are of the form x.y.z, but the list encodes
              // them of the form Lx/y/z;. Inner classes have '$' for both Java level class
              // names in strings, and hidden API lists.
              std::string str = HiddenApi::ToInternalName(name);
              // Note: we can query the lists directly, as HiddenApi added classes that own
              // private methods and fields in them.
              // We don't add class names to the `strings_` set as we know method/field names
              // don't have '.' or '/'. All hidden API class names have a '/'.
              if (hidden_api_.IsInRestrictionList(str)) {
                classes_.insert(str);
              } else if (hidden_api_.IsInRestrictionList(name)) {
                // Could be something passed to JNI.
                classes_.insert(name);
              } else {
                // We only keep track of the location for strings, as these will be the
                // field/method names the user is interested in.
                strings_.insert(name);
                reflection_locations_[name].push_back(method.GetReference());
              }
            }
            break;
          }
          case Instruction::INVOKE_DIRECT:
          case Instruction::INVOKE_INTERFACE:
          case Instruction::INVOKE_STATIC:
          case Instruction::INVOKE_SUPER:
          case Instruction::INVOKE_VIRTUAL: {
            CheckMethod(inst->VRegB_35c(), resolver, method.GetReference());
            break;
          }

          case Instruction::INVOKE_DIRECT_RANGE:
          case Instruction::INVOKE_INTERFACE_RANGE:
          case Instruction::INVOKE_STATIC_RANGE:
          case Instruction::INVOKE_SUPER_RANGE:
          case Instruction::INVOKE_VIRTUAL_RANGE: {
            CheckMethod(inst->VRegB_3rc(), resolver, method.GetReference());
            break;
          }

          case Instruction::IGET:
          case Instruction::IGET_WIDE:
          case Instruction::IGET_OBJECT:
          case Instruction::IGET_BOOLEAN:
          case Instruction::IGET_BYTE:
          case Instruction::IGET_CHAR:
          case Instruction::IGET_SHORT: {
            CheckField(inst->VRegC_22c(), resolver, method.GetReference());
            break;
          }

          case Instruction::IPUT:
          case Instruction::IPUT_WIDE:
          case Instruction::IPUT_OBJECT:
          case Instruction::IPUT_BOOLEAN:
          case Instruction::IPUT_BYTE:
          case Instruction::IPUT_CHAR:
          case Instruction::IPUT_SHORT: {
            CheckField(inst->VRegC_22c(), resolver, method.GetReference());
            break;
          }

          case Instruction::SGET:
          case Instruction::SGET_WIDE:
          case Instruction::SGET_OBJECT:
          case Instruction::SGET_BOOLEAN:
          case Instruction::SGET_BYTE:
          case Instruction::SGET_CHAR:
          case Instruction::SGET_SHORT: {
            CheckField(inst->VRegB_21c(), resolver, method.GetReference());
            break;
          }

          case Instruction::SPUT:
          case Instruction::SPUT_WIDE:
          case Instruction::SPUT_OBJECT:
          case Instruction::SPUT_BOOLEAN:
          case Instruction::SPUT_BYTE:
          case Instruction::SPUT_CHAR:
          case Instruction::SPUT_SHORT: {
            CheckField(inst->VRegB_21c(), resolver, method.GetReference());
            break;
          }

          default:
            break;
        }
      }
    }
  }
}

void HiddenApiFinder::Run(const std::vector<std::unique_ptr<VeridexResolver>>& resolvers) {
  for (const std::unique_ptr<VeridexResolver>& resolver : resolvers) {
    CollectAccesses(resolver.get());
  }
}

void HiddenApiFinder::Dump(std::ostream& os,
                           HiddenApiStats* stats,
                           bool dump_reflection) {
  static const char* kPrefix = "       ";
  stats->linking_count = method_locations_.size() + field_locations_.size();

  // Dump methods from hidden APIs linked against.
  for (const std::pair<const std::string,
                       std::vector<MethodReference>>& pair : method_locations_) {
    HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(pair.first);
    stats->api_counts[api_list]++;
    os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";
    os << std::endl;
    for (const MethodReference& ref : pair.second) {
      os << kPrefix << HiddenApi::GetApiMethodName(ref) << std::endl;
    }
    os << std::endl;
  }

  // Dump fields from hidden APIs linked against.
  for (const std::pair<const std::string,
                       std::vector<MethodReference>>& pair : field_locations_) {
    HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(pair.first);
    stats->api_counts[api_list]++;
    os << "#" << ++stats->count << ": Linking " << api_list << " " << pair.first << " use(s):";
    os << std::endl;
    for (const MethodReference& ref : pair.second) {
      os << kPrefix << HiddenApi::GetApiMethodName(ref) << std::endl;
    }
    os << std::endl;
  }

  if (dump_reflection) {
    // Dump potential reflection uses.
    for (const std::string& cls : classes_) {
      for (const std::string& name : strings_) {
        std::string full_name = cls + "->" + name;
        HiddenApiAccessFlags::ApiList api_list = hidden_api_.GetApiList(full_name);
        stats->api_counts[api_list]++;
        if (api_list != HiddenApiAccessFlags::kWhitelist) {
          stats->reflection_count++;
          os << "#" << ++stats->count << ": Reflection " << api_list << " " << full_name
             << " potential use(s):";
          os << std::endl;
          for (const MethodReference& ref : reflection_locations_[name]) {
            os << kPrefix << HiddenApi::GetApiMethodName(ref) << std::endl;
          }
          os << std::endl;
        }
      }
    }
  }
}

}  // namespace art
