// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "crazy_linker_search_path_list.h"

#include "crazy_linker.h"
#include "crazy_linker_debug.h"
#include "crazy_linker_system.h"
#include "crazy_linker_zip.h"

#include <utility>

#include <string.h>

namespace crazy {

namespace {

// Helper class used to parse over the items of two column-separated lists.
// Usage is the following:
//  1) Create new instance, passing the first and second list as parameters.
//  2) Call NextItem() in a loop until it returns false. Each call will
//     return the current item.
//
// Items of the first list are returned in order before items of the second
// list.
class MultiListParser {
 public:
  // Constructor.
  MultiListParser(const String& a_list, const String& b_list)
      : p_(a_list.cbegin()), end_(a_list.cend()), b_list_(b_list) {}

  // Grab next item. On success return true and sets |*result|. On end of list,
  // just return false.
  bool NextItem(String* result) {
    for (;;) {
      if (p_ == end_) {
        if (p_ != b_list_.cend()) {
          p_ = b_list_.cbegin();
          end_ = b_list_.cend();
          continue;
        }
        return false;
      }
      // compute current list item, and next item start at the same time.
      const char* item = p_;
      const char* item_end = item;
      while (item_end < end_ && item_end[0] != ':')
        item_end++;

      p_ = item_end + (item_end < end_);

      if (item_end > item) {  // Skip over empty entries.
        result->Assign(item, item_end - item);
        return true;
      }
    }
  }

 private:
  const char* p_;
  const char* end_;
  const String& b_list_;
};

// Look into zip archive at |zip_path| for a file named |file_name|.
// As a special convenience trick, this will also try to find a file with
// the same name with a 'crazy.' prefix. In other words, when looking for
// 'lib/libfoo.so', this will first look for 'lib/libfoo.so', then for
// 'lib/crazy.libfoo.so'. This allows storing uncompressed libraries inside
// Android APKs while preventing the system from extracting them at installation
// time (which will always happen before Android M). Note that these files
// should just be renamed, i.e. their internal soname should still be
// 'libfoo.so'.
//
// On success, return offset within zip archive, or CRAZY_OFFSET_FAILED
// if the library is not found.
int32_t FindLibFileInZipArchive(const char* zip_path, const char* file_name) {
  // First attempt is direct lookup.
  int32_t offset = FindStartOffsetOfFileInZipFile(zip_path, file_name);
  if (offset != CRAZY_OFFSET_FAILED) {
    LOG("  FOUND_IN_ZIP %s!%s @ 0x%x", zip_path, file_name, offset);
    return offset;
  }

  // Second attempt adding a crazy. prefix to the library name.
  String crazy_name;
  const char* pos = ::strrchr(file_name, '/');
  if (pos) {
    crazy_name.Assign(file_name, (pos + 1 - file_name));
    file_name = pos + 1;
  }
  crazy_name.Append("crazy.");
  crazy_name.Append(file_name);

  offset = FindStartOffsetOfFileInZipFile(zip_path, crazy_name.c_str());
  if (offset != CRAZY_OFFSET_FAILED) {
    LOG("  FOUND IN ZIP %s!%s @ 0x%x", zip_path, crazy_name.c_str(), offset);
  }
  return offset;
}

// Try to find the library file pointed by |path|.
// If |path| contains an exclamation mark, this is interpreted as a separator
// between a zip archive file path, and a file contained inside it.
// Also supports crazy. prefix for storing renamed libraries inside the zip
// archive (see comment for FindLibFileInZipArchive).
SearchPathList::Result FindLibFile(const char* path) {
  // An exclamation mark in the file name indicates that one should look
  // inside a zip archive. This is supported by the platform, see the
  // "Opening shared libraries directly from an APK" in the following article:
  // https://github.com/aosp-mirror/platform_bionic/blob/master/android-changes-for-ndk-developers.md
  const char* bang = ::strchr(path, '!');
  if (bang) {
    if (bang == path || bang[1] == '\0') {
      // An initial or final '!' is always an error.
      LOG("  INVALID_ZIP_PATH %s", path);
    } else {
      String zip_path = MakeAbsolutePathFrom(path, bang - path);
      const char* file_name = bang + 1;
      int32_t offset = FindLibFileInZipArchive(zip_path.c_str(), bang + 1);
      if (offset != CRAZY_OFFSET_FAILED) {
        return {std::move(zip_path), offset};
      }
    }
  } else {
    // Regular file path.
    String file_path = MakeAbsolutePathFrom(path);
    if (PathIsFile(file_path.c_str())) {
      LOG("  FOUND FILE %s", file_path.c_str());
      return {std::move(file_path), 0};
    }
  }

  LOG("  skip %s", path);
  return {};
}

}  // namespace

void SearchPathList::Reset() {
  list_.Resize(0);
  env_list_.Resize(0);
}

void SearchPathList::ResetFromEnv(const char* var_name) {
  Reset();
  const char* env = GetEnv(var_name);
  if (env && *env)
    env_list_ = env;
}

void SearchPathList::AddPaths(const char* list, const char* list_end) {
  // Append a column to the current list, if necessary
  if (list_.size() > 0 && list_[list_.size() - 1] != ':')
    list_ += ':';
  list_.Append(list, list_end - list);
}

SearchPathList::Result SearchPathList::FindFile(const char* file_name) const {
  LOG("Looking for %s", file_name);

  if (::strchr(file_name, '/') != nullptr ||
      ::strchr(file_name, '!') != nullptr) {
    // This is an absolute or relative file path, so ignore the search list.
    return FindLibFile(file_name);
  }

  // Build full list by appending the env_list_ after the regular one.
  MultiListParser parser(list_, env_list_);
  String file_path;
  Result result;
  while (parser.NextItem(&file_path)) {
    // Add trailing directory separator if needed.
    if (file_path[file_path.size() - 1] != '/')
      file_path += '/';

    file_path += file_name;

    result = FindLibFile(file_path.c_str());
    if (result.IsValid()) {
      return result;
    }
    LOG("  SKIPPED %s", file_path.c_str());
  }

  LOG("  MISSING %s", file_name);
  return result;
}

}  // namespace crazy
