// Copyright (c) 2017 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 "sql/vfs_wrapper.h"

#include <algorithm>
#include <string>
#include <vector>

#include "base/check_op.h"
#include "base/debug/leak_annotations.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/strings/string_piece.h"
#include "build/build_config.h"

#if defined(OS_MAC)
#include "base/mac/mac_util.h"
#endif

#if defined(OS_FUCHSIA)
#include "sql/vfs_wrapper_fuchsia.h"
#endif

namespace sql {
namespace {

// https://www.sqlite.org/vfs.html - documents the overall VFS system.
//
// https://www.sqlite.org/c3ref/vfs.html - VFS methods.  This code tucks the
// wrapped VFS pointer into the wrapper's pAppData pointer.
//
// https://www.sqlite.org/c3ref/file.html - instance of an open file.  This code
// allocates a VfsFile for this, which contains a pointer to the wrapped file.
// Idiomatic SQLite would take the wrapped VFS szOsFile and increase it to store
// additional data as a prefix.

sqlite3_vfs* GetWrappedVfs(sqlite3_vfs* wrapped_vfs) {
  return static_cast<sqlite3_vfs*>(wrapped_vfs->pAppData);
}

VfsFile* AsVfsFile(sqlite3_file* wrapper_file) {
  return reinterpret_cast<VfsFile*>(wrapper_file);
}

sqlite3_file* GetWrappedFile(sqlite3_file* wrapper_file) {
  return AsVfsFile(wrapper_file)->wrapped_file;
}

int Close(sqlite3_file* sqlite_file)
{
  VfsFile* file = AsVfsFile(sqlite_file);

#if defined(OS_FUCHSIA)
  FuchsiaVfsUnlock(sqlite_file, SQLITE_LOCK_NONE);
#endif

  int r = file->wrapped_file->pMethods->xClose(file->wrapped_file);
  sqlite3_free(file->wrapped_file);

  // Memory will be freed with sqlite3_free(), so the destructor needs to be
  // called explicitly.
  file->~VfsFile();
  memset(file, '\0', sizeof(*file));
  return r;
}

int Read(sqlite3_file* sqlite_file, void* buf, int amt, sqlite3_int64 ofs)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xRead(wrapped_file, buf, amt, ofs);
}

int Write(sqlite3_file* sqlite_file, const void* buf, int amt,
          sqlite3_int64 ofs)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xWrite(wrapped_file, buf, amt, ofs);
}

int Truncate(sqlite3_file* sqlite_file, sqlite3_int64 size)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xTruncate(wrapped_file, size);
}

int Sync(sqlite3_file* sqlite_file, int flags)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xSync(wrapped_file, flags);
}

int FileSize(sqlite3_file* sqlite_file, sqlite3_int64* size)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xFileSize(wrapped_file, size);
}

#if !defined(OS_FUCHSIA)

int Lock(sqlite3_file* sqlite_file, int file_lock)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xLock(wrapped_file, file_lock);
}

int Unlock(sqlite3_file* sqlite_file, int file_lock)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xUnlock(wrapped_file, file_lock);
}

int CheckReservedLock(sqlite3_file* sqlite_file, int* result)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xCheckReservedLock(wrapped_file, result);
}

#endif  // !defined(OS_FUCHSIA)

int FileControl(sqlite3_file* sqlite_file, int op, void* arg)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xFileControl(wrapped_file, op, arg);
}

int SectorSize(sqlite3_file* sqlite_file)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xSectorSize(wrapped_file);
}

int DeviceCharacteristics(sqlite3_file* sqlite_file)
{
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xDeviceCharacteristics(wrapped_file);
}

int ShmMap(sqlite3_file *sqlite_file, int region, int size,
           int extend, void volatile **pp) {
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xShmMap(
      wrapped_file, region, size, extend, pp);
}

int ShmLock(sqlite3_file *sqlite_file, int ofst, int n, int flags) {
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xShmLock(wrapped_file, ofst, n, flags);
}

void ShmBarrier(sqlite3_file *sqlite_file) {
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  wrapped_file->pMethods->xShmBarrier(wrapped_file);
}

int ShmUnmap(sqlite3_file *sqlite_file, int del) {
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xShmUnmap(wrapped_file, del);
}

int Fetch(sqlite3_file *sqlite_file, sqlite3_int64 off, int amt, void **pp) {
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xFetch(wrapped_file, off, amt, pp);
}

int Unfetch(sqlite3_file *sqlite_file, sqlite3_int64 off, void *p) {
  sqlite3_file* wrapped_file = GetWrappedFile(sqlite_file);
  return wrapped_file->pMethods->xUnfetch(wrapped_file, off, p);
}

int Open(sqlite3_vfs* vfs, const char* file_name, sqlite3_file* wrapper_file,
         int desired_flags, int* used_flags) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);

  sqlite3_file* wrapped_file = static_cast<sqlite3_file*>(
      sqlite3_malloc(wrapped_vfs->szOsFile));
  if (!wrapped_file)
    return SQLITE_NOMEM;

  // NOTE(shess): SQLite's unixOpen() makes assumptions about the structure of
  // |file_name|.  Do not pass a local copy, here, only the passed-in value.
  int rc = wrapped_vfs->xOpen(wrapped_vfs,
                              file_name, wrapped_file,
                              desired_flags, used_flags);
  if (rc != SQLITE_OK) {
    sqlite3_free(wrapped_file);
    return rc;
  }
  // NOTE(shess): Any early exit from here needs to call xClose() on
  // |wrapped_file|.

#if defined(OS_MAC)
  // When opening journal files, propagate time-machine exclusion from db.
  static int kJournalFlags =
      SQLITE_OPEN_MAIN_JOURNAL | SQLITE_OPEN_TEMP_JOURNAL |
      SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL;
  if (file_name && (desired_flags & kJournalFlags)) {
    // https://www.sqlite.org/c3ref/vfs.html indicates that the journal path
    // will have a suffix separated by "-" from the main database file name.
    base::StringPiece file_name_string_piece(file_name);
    size_t dash_index = file_name_string_piece.rfind('-');
    if (dash_index != base::StringPiece::npos) {
      base::StringPiece db_name(file_name, dash_index);
      if (base::mac::GetFileBackupExclusion(base::FilePath(db_name))) {
        base::mac::SetFileBackupExclusion(
            base::FilePath(file_name_string_piece));
      }
    }
  }
#endif

  // |iVersion| determines what methods SQLite may call on the instance.
  // Having the methods which can't be proxied return an error may cause SQLite
  // to operate differently than if it didn't call those methods at all. To be
  // on the safe side, the wrapper sqlite3_io_methods version perfectly matches
  // the version of the wrapped files.
  //
  // At a first glance, it might be tempting to simplify the code by
  // restricting wrapping support to VFS version 3. However, this might fail on
  // Mac.
  //
  // On Mac, SQLite built with SQLITE_ENABLE_LOCKING_STYLE ends up using a VFS
  // that dynamically dispatches between a few variants of sqlite3_io_methods,
  // based on whether the opened database is on a local or on a remote (AFS,
  // NFS) filesystem. Some variants return a VFS version 1 structure.
  VfsFile* file = AsVfsFile(wrapper_file);

  // Call constructor explicitly since the memory is already allocated.
  new (file) VfsFile();

  file->wrapped_file = wrapped_file;

#if defined(OS_FUCHSIA)
  file->file_name = file_name;
  file->lock_level = SQLITE_LOCK_NONE;
#endif

  if (wrapped_file->pMethods->iVersion == 1) {
    static const sqlite3_io_methods io_methods = {
      1,
      Close,
      Read,
      Write,
      Truncate,
      Sync,
      FileSize,
#if !defined(OS_FUCHSIA)
      Lock,
      Unlock,
      CheckReservedLock,
#else
      FuchsiaVfsLock,
      FuchsiaVfsUnlock,
      FuchsiaVfsCheckReservedLock,
#endif
      FileControl,
      SectorSize,
      DeviceCharacteristics,
    };
    file->methods = &io_methods;
  } else if (wrapped_file->pMethods->iVersion == 2) {
    static const sqlite3_io_methods io_methods = {
      2,
      Close,
      Read,
      Write,
      Truncate,
      Sync,
      FileSize,
#if !defined(OS_FUCHSIA)
      Lock,
      Unlock,
      CheckReservedLock,
#else
      FuchsiaVfsLock,
      FuchsiaVfsUnlock,
      FuchsiaVfsCheckReservedLock,
#endif
      FileControl,
      SectorSize,
      DeviceCharacteristics,
      // Methods above are valid for version 1.
      ShmMap,
      ShmLock,
      ShmBarrier,
      ShmUnmap,
    };
    file->methods = &io_methods;
  } else {
    static const sqlite3_io_methods io_methods = {
      3,
      Close,
      Read,
      Write,
      Truncate,
      Sync,
      FileSize,
#if !defined(OS_FUCHSIA)
      Lock,
      Unlock,
      CheckReservedLock,
#else
      FuchsiaVfsLock,
      FuchsiaVfsUnlock,
      FuchsiaVfsCheckReservedLock,
#endif
      FileControl,
      SectorSize,
      DeviceCharacteristics,
      // Methods above are valid for version 1.
      ShmMap,
      ShmLock,
      ShmBarrier,
      ShmUnmap,
      // Methods above are valid for version 2.
      Fetch,
      Unfetch,
    };
    file->methods = &io_methods;
  }
  return SQLITE_OK;
}

int Delete(sqlite3_vfs* vfs, const char* file_name, int sync_dir) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xDelete(wrapped_vfs, file_name, sync_dir);
}

int Access(sqlite3_vfs* vfs, const char* file_name, int flag, int* res) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xAccess(wrapped_vfs, file_name, flag, res);
}

int FullPathname(sqlite3_vfs* vfs, const char* relative_path,
                 int buf_size, char* absolute_path) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xFullPathname(
      wrapped_vfs, relative_path, buf_size, absolute_path);
}

int Randomness(sqlite3_vfs* vfs, int buf_size, char* buffer) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xRandomness(wrapped_vfs, buf_size, buffer);
}

int Sleep(sqlite3_vfs* vfs, int microseconds) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xSleep(wrapped_vfs, microseconds);
}

int GetLastError(sqlite3_vfs* vfs, int e, char* s) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xGetLastError(wrapped_vfs, e, s);
}

int CurrentTimeInt64(sqlite3_vfs* vfs, sqlite3_int64* now) {
  sqlite3_vfs* wrapped_vfs = GetWrappedVfs(vfs);
  return wrapped_vfs->xCurrentTimeInt64(wrapped_vfs, now);
}

}  // namespace

sqlite3_vfs* VFSWrapper() {
  const char* kVFSName = "VFSWrapper";

  // Return existing version if already registered.
  {
    sqlite3_vfs* vfs = sqlite3_vfs_find(kVFSName);
    if (vfs)
      return vfs;
  }

  // Get the default VFS on all platforms except Fuchsia.
  const char* base_vfs_name = nullptr;
#if defined(OS_FUCHSIA)
  base_vfs_name = "unix-none";
#endif
  sqlite3_vfs* wrapped_vfs = sqlite3_vfs_find(base_vfs_name);

  // Give up if there is no VFS implementation for the current platform.
  if (!wrapped_vfs) {
    NOTREACHED();
    return nullptr;
  }

  std::unique_ptr<sqlite3_vfs, std::function<void(sqlite3_vfs*)>> wrapper_vfs(
      static_cast<sqlite3_vfs*>(sqlite3_malloc(sizeof(sqlite3_vfs))),
      [](sqlite3_vfs* v) {
        sqlite3_free(v);
      });
  memset(wrapper_vfs.get(), '\0', sizeof(sqlite3_vfs));

  // VFS implementations should always work with a SQLite that only knows about
  // earlier versions.
  constexpr int kSqliteVfsApiVersion = 3;
  wrapper_vfs->iVersion = kSqliteVfsApiVersion;

  // All the SQLite VFS implementations used by Chrome should support the
  // version proxied here.
  DCHECK_GE(wrapped_vfs->iVersion, kSqliteVfsApiVersion);

  // Caller of xOpen() allocates this much space.
  wrapper_vfs->szOsFile = sizeof(VfsFile);

  wrapper_vfs->mxPathname = wrapped_vfs->mxPathname;
  wrapper_vfs->pNext = nullptr;  // Field used by SQLite.
  wrapper_vfs->zName = kVFSName;

  // Keep a reference to the wrapped vfs for use in methods.
  wrapper_vfs->pAppData = wrapped_vfs;

  // VFS methods.
  wrapper_vfs->xOpen = &Open;
  wrapper_vfs->xDelete = &Delete;
  wrapper_vfs->xAccess = &Access;
  wrapper_vfs->xFullPathname = &FullPathname;

  // SQLite's dynamic extension loading is disabled in Chrome. Not proxying
  // these methods lets us ship less logic and provides a tiny bit of extra
  // security, as we know for sure that SQLite will not dynamically load code.
  wrapper_vfs->xDlOpen = nullptr;
  wrapper_vfs->xDlError = nullptr;
  wrapper_vfs->xDlSym = nullptr;
  wrapper_vfs->xDlClose = nullptr;

  wrapper_vfs->xRandomness = &Randomness;
  wrapper_vfs->xSleep = &Sleep;

  // |xCurrentTime| is null when SQLite is built with SQLITE_OMIT_DEPRECATED, so
  // it does not need to be proxied.
  wrapper_vfs->xCurrentTime = nullptr;

  wrapper_vfs->xGetLastError = &GetLastError;

  // The methods above are in version 1 of SQLite's VFS API.

  DCHECK(wrapped_vfs->xCurrentTimeInt64 != nullptr);
  wrapper_vfs->xCurrentTimeInt64 = &CurrentTimeInt64;

  // The methods above are in version 2 of SQLite's VFS API.

  // The VFS system call interception API is intended for very low-level SQLite
  // testing and tweaks. Proxying these methods is not necessary because Chrome
  // does not do very low-level SQLite testing, and the VFS wrapper supports all
  // the needed tweaks.
  wrapper_vfs->xSetSystemCall = nullptr;
  wrapper_vfs->xGetSystemCall = nullptr;
  wrapper_vfs->xNextSystemCall = nullptr;

  // The methods above are in version 3 of sqlite_vfs.

  if (SQLITE_OK == sqlite3_vfs_register(wrapper_vfs.get(), 0)) {
    ANNOTATE_LEAKING_OBJECT_PTR(wrapper_vfs.get());
    wrapper_vfs.release();
  }

  return sqlite3_vfs_find(kVFSName);
}

}  // namespace sql
