Commit message: None
CVE: None
Vulnerability description: None

Project: Chrome

int SQLiteDatabase::AuthorizerFunction(void* user_data,
                                       int action_code,
                                       const char* parameter1,
                                       const char* parameter2,
                                       const char* /*databaseName*/,
                                       const char* /*trigger_or_view*/) {
  DatabaseAuthorizer* auth = static_cast<DatabaseAuthorizer*>(user_data);
  DCHECK(auth);

  switch (action_code) {
    case SQLITE_CREATE_INDEX:
      return auth->CreateIndex(parameter1, parameter2);
    case SQLITE_CREATE_TABLE:
      return auth->CreateTable(parameter1);
    case SQLITE_CREATE_TEMP_INDEX:
      return auth->CreateTempIndex(parameter1, parameter2);
    case SQLITE_CREATE_TEMP_TABLE:
      return auth->CreateTempTable(parameter1);
    case SQLITE_CREATE_TEMP_TRIGGER:
      return auth->CreateTempTrigger(parameter1, parameter2);
    case SQLITE_CREATE_TEMP_VIEW:
      return auth->CreateTempView(parameter1);
    case SQLITE_CREATE_TRIGGER:
      return auth->CreateTrigger(parameter1, parameter2);
    case SQLITE_CREATE_VIEW:
      return auth->CreateView(parameter1);
    case SQLITE_DELETE:
      return auth->AllowDelete(parameter1);
    case SQLITE_DROP_INDEX:
      return auth->DropIndex(parameter1, parameter2);
    case SQLITE_DROP_TABLE:
      return auth->DropTable(parameter1);
    case SQLITE_DROP_TEMP_INDEX:
      return auth->DropTempIndex(parameter1, parameter2);
    case SQLITE_DROP_TEMP_TABLE:
      return auth->DropTempTable(parameter1);
    case SQLITE_DROP_TEMP_TRIGGER:
      return auth->DropTempTrigger(parameter1, parameter2);
    case SQLITE_DROP_TEMP_VIEW:
      return auth->DropTempView(parameter1);
    case SQLITE_DROP_TRIGGER:
      return auth->DropTrigger(parameter1, parameter2);
    case SQLITE_DROP_VIEW:
      return auth->DropView(parameter1);
    case SQLITE_INSERT:
      return auth->AllowInsert(parameter1);
    case SQLITE_PRAGMA:
      return auth->AllowPragma(parameter1, parameter2);
    case SQLITE_READ:
      return auth->AllowRead(parameter1, parameter2);
    case SQLITE_SELECT:
      return auth->AllowSelect();
    case SQLITE_TRANSACTION:
      return auth->AllowTransaction();
    case SQLITE_UPDATE:
      return auth->AllowUpdate(parameter1, parameter2);
    case SQLITE_ATTACH:
      return kSQLAuthDeny;
    case SQLITE_DETACH:
      return kSQLAuthDeny;
    case SQLITE_ALTER_TABLE:
      return auth->AllowAlterTable(parameter1, parameter2);
    case SQLITE_REINDEX:
      return auth->AllowReindex(parameter1);
    case SQLITE_ANALYZE:
      return auth->AllowAnalyze(parameter1);
    case SQLITE_CREATE_VTABLE:
      return auth->CreateVTable(parameter1, parameter2);
    case SQLITE_DROP_VTABLE:
      return auth->DropVTable(parameter1, parameter2);
    case SQLITE_FUNCTION:
      return auth->AllowFunction(parameter2);
    case SQLITE_SAVEPOINT:
      return kSQLAuthDeny;
    case SQLITE_RECURSIVE:
      return kSQLAuthDeny;
  }
  NOTREACHED();
  return kSQLAuthDeny;
}

Project: Chrome

void SQLiteDatabase::Close() {
  if (db_) {
    sqlite3* db = db_;
    {
      MutexLocker locker(database_closing_mutex_);
      db_ = nullptr;
    }
    sqlite3_close(db);
  }

  opening_thread_ = 0;
  open_error_ = SQLITE_ERROR;
  open_error_message_ = CString();
}

Project: Chrome

void SQLiteDatabase::EnableAuthorizer(bool enable) {
  if (authorizer_ && enable)
    sqlite3_set_authorizer(db_, SQLiteDatabase::AuthorizerFunction,
                           authorizer_.Get());
  else
    sqlite3_set_authorizer(db_, nullptr, nullptr);
}

Project: Chrome

bool SQLiteDatabase::ExecuteCommand(const String& sql) {
  return SQLiteStatement(*this, sql).ExecuteCommand();
}

Project: Chrome

int64_t SQLiteDatabase::FreeSpaceSize() {
  int64_t freelist_count = 0;

  {
    MutexLocker locker(authorizer_lock_);
    EnableAuthorizer(false);
    SQLiteStatement statement(*this, "PRAGMA freelist_count");
    freelist_count = statement.GetColumnInt64(0);
    EnableAuthorizer(true);
  }

  return freelist_count * PageSize();
}

Project: Chrome

bool SQLiteDatabase::IsAutoCommitOn() const {
  return sqlite3_get_autocommit(db_);
}

Project: Chrome

int SQLiteDatabase::LastChanges() {
  if (!db_)
    return 0;

  return sqlite3_total_changes(db_) - last_changes_count_;
}

Project: Chrome

int SQLiteDatabase::LastError() {
  return db_ ? sqlite3_errcode(db_) : open_error_;
}

Project: Chrome

const char* SQLiteDatabase::LastErrorMsg() {
  if (db_)
    return sqlite3_errmsg(db_);
  return open_error_message_.IsNull() ? kNotOpenErrorMessage
                                      : open_error_message_.data();
}

Project: Chrome

int SQLiteDatabase::PageSize() {
  if (page_size_ == -1) {
    MutexLocker locker(authorizer_lock_);
    EnableAuthorizer(false);

    SQLiteStatement statement(*this, "PRAGMA page_size");
    page_size_ = statement.GetColumnInt(0);

    EnableAuthorizer(true);
  }

  return page_size_;
}

Project: Chrome

int SQLiteDatabase::RunIncrementalVacuumCommand() {
  MutexLocker locker(authorizer_lock_);
  EnableAuthorizer(false);

  if (!ExecuteCommand("PRAGMA incremental_vacuum"))
    SQL_DVLOG(1) << "Unable to run incremental vacuum - " << LastErrorMsg();

  EnableAuthorizer(true);
  return LastError();
}

Project: Chrome

int SQLiteDatabase::RunVacuumCommand() {
  if (!ExecuteCommand("VACUUM;"))
    SQL_DVLOG(1) << "Unable to vacuum database -" << LastErrorMsg();
  return LastError();
}

Project: Chrome

SQLiteDatabase::SQLiteDatabase()
    : db_(nullptr),
      page_size_(-1),
      transaction_in_progress_(false),
      opening_thread_(0),
      open_error_(SQLITE_ERROR),
      open_error_message_(),
      last_changes_count_(0) {
}

Project: Chrome

void SQLiteDatabase::SetAuthorizer(DatabaseAuthorizer* auth) {
  if (!db_) {
    NOTREACHED() << "Attempt to set an authorizer on a non-open SQL database";
    return;
  }

  MutexLocker locker(authorizer_lock_);

  authorizer_ = auth;

  EnableAuthorizer(true);
}

Project: Chrome

void SQLiteDatabase::SetBusyTimeout(int ms) {
  if (db_)
    sqlite3_busy_timeout(db_, ms);
  else
    SQL_DVLOG(1) << "BusyTimeout set on non-open database";
}

Project: Chrome

void SQLiteDatabase::SetMaximumSize(int64_t size) {
  if (size < 0)
    size = 0;

  int current_page_size = PageSize();

  DCHECK(current_page_size || !db_);
  int64_t new_max_page_count = current_page_size ? size / current_page_size : 0;

  MutexLocker locker(authorizer_lock_);
  EnableAuthorizer(false);

  SQLiteStatement statement(
      *this, "PRAGMA max_page_count = " + String::Number(new_max_page_count));
  statement.Prepare();
  if (statement.Step() != kSQLResultRow)
    DLOG(ERROR) << "Failed to set maximum size of database to " << size
                << " bytes";

  EnableAuthorizer(true);
}

Project: Chrome

bool SQLiteDatabase::TableExists(const String& tablename) {
  if (!IsOpen())
    return false;

  String statement =
      "SELECT name FROM sqlite_master WHERE type = 'table' AND name = '" +
      tablename + "';";

  SQLiteStatement sql(*this, statement);
  sql.Prepare();
  return sql.Step() == SQLITE_ROW;
}

Project: Chrome

int64_t SQLiteDatabase::TotalSize() {
  int64_t page_count = 0;

  {
    MutexLocker locker(authorizer_lock_);
    EnableAuthorizer(false);
    SQLiteStatement statement(*this, "PRAGMA page_count");
    page_count = statement.GetColumnInt64(0);
    EnableAuthorizer(true);
  }

  return page_count * PageSize();
}

Project: Chrome

void SQLiteDatabase::UpdateLastChangesCount() {
  if (!db_)
    return;

  last_changes_count_ = sqlite3_total_changes(db_);
}

Project: Chrome

SQLiteDatabase::~SQLiteDatabase() {
  Close();
}