websql: Use a dedicated SQLite VFS.
This is the first step in removing our SQLite VFS patches that support
WebSQL. After this CL proves stable, a follow-up will remove the SQLite
patches.
Bug: 925739
Change-Id: I9c709242f815ffa4e97787c37cea247a222c9990
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1438818
Commit-Queue: Victor Costan <pwnall@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: Chris Mumford <cmumford@google.com>
Reviewed-by: Joshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641417}
diff --git a/third_party/blink/renderer/modules/webdatabase/BUILD.gn b/third_party/blink/renderer/modules/webdatabase/BUILD.gn
index 2f66e4c..cad740db 100644
--- a/third_party/blink/renderer/modules/webdatabase/BUILD.gn
+++ b/third_party/blink/renderer/modules/webdatabase/BUILD.gn
@@ -56,14 +56,16 @@
"sql_transaction_state.h",
"sql_transaction_state_machine.cc",
"sql_transaction_state_machine.h",
+ "sqlite/sandboxed_vfs.cc",
+ "sqlite/sandboxed_vfs.h",
+ "sqlite/sandboxed_vfs_file.cc",
+ "sqlite/sandboxed_vfs_file.h",
"sqlite/sql_log.h",
"sqlite/sql_value.cc",
"sqlite/sql_value.h",
"sqlite/sqlite_authorizer.cc",
"sqlite/sqlite_database.cc",
"sqlite/sqlite_database.h",
- "sqlite/sqlite_file_system.cc",
- "sqlite/sqlite_file_system.h",
"sqlite/sqlite_statement.cc",
"sqlite/sqlite_statement.h",
"sqlite/sqlite_transaction.cc",
@@ -77,13 +79,4 @@
"//sql",
"//third_party/sqlite",
]
-
- if (is_win) {
- sources += [ "sqlite/sqlite_file_system_win.cc" ]
- } else if (is_posix || is_fuchsia) {
- sources += [ "sqlite/sqlite_file_system_posix.cc" ]
- }
-
- # Expose chromium_sqlite3_* functions from Chromium's patched SQLite.
- defines = [ "CHROMIUM_SQLITE_INTERNALS" ] # So that sqlite3.h is not included without this set.
}
diff --git a/third_party/blink/renderer/modules/webdatabase/database_tracker.cc b/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
index 6a33c79..14b3544 100644
--- a/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
+++ b/third_party/blink/renderer/modules/webdatabase/database_tracker.cc
@@ -43,7 +43,6 @@
#include "third_party/blink/renderer/modules/webdatabase/database_client.h"
#include "third_party/blink/renderer/modules/webdatabase/database_context.h"
#include "third_party/blink/renderer/modules/webdatabase/quota_tracker.h"
-#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
@@ -67,7 +66,6 @@
}
DatabaseTracker::DatabaseTracker() {
- SQLiteFileSystem::InitializeSQLite();
}
bool DatabaseTracker::CanEstablishDatabase(DatabaseContext* database_context,
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS b/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS
index 1a2948b..0bdaea5f 100644
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS
@@ -1,4 +1,6 @@
include_rules = [
+ "+base/files/file.h",
+ "+base/threading/platform_thread.h",
"+sql/initialization.h",
"+third_party/sqlite/sqlite3.h",
]
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.cc
new file mode 100644
index 0000000..92bfd37
--- /dev/null
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.cc
@@ -0,0 +1,319 @@
+// Copyright 2019 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 "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h"
+
+#include <algorithm>
+#include <cstring>
+#include <string>
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/logging.h"
+#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
+#include "sql/initialization.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h"
+#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
+#include "third_party/sqlite/sqlite3.h"
+
+#if OS_WIN
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace blink {
+
+namespace {
+
+// Name used to register the VFS with SQLite. Must be unique within Chrome.
+constexpr char kSqliteVfsName[] = "renderer_sandboxed_vfs";
+
+// Extracts the SandboxedVfs* stashed in a SQLite VFS structure.
+SandboxedVfs* SandboxedVfsFromSqliteVfs(sqlite3_vfs* vfs) {
+ DCHECK(vfs);
+ return reinterpret_cast<SandboxedVfs*>(vfs->pAppData);
+}
+
+int SandboxedVfsOpen(sqlite3_vfs* vfs,
+ const char* full_path,
+ sqlite3_file* result_file,
+ int requested_flags,
+ int* granted_flags) {
+ return SandboxedVfsFromSqliteVfs(vfs)->Open(full_path, result_file,
+ requested_flags, granted_flags);
+}
+int SandboxedVfsDelete(sqlite3_vfs* vfs, const char* full_path, int sync_dir) {
+ return SandboxedVfsFromSqliteVfs(vfs)->Delete(full_path, sync_dir);
+}
+int SandboxedVfsAccess(sqlite3_vfs* vfs,
+ const char* full_path,
+ int flags,
+ int* result) {
+ return SandboxedVfsFromSqliteVfs(vfs)->Access(full_path, flags, result);
+}
+int SandboxedVfsFullPathname(sqlite3_vfs* vfs,
+ const char* file_path,
+ int result_size,
+ char* result) {
+ return SandboxedVfsFromSqliteVfs(vfs)->FullPathname(file_path, result_size,
+ result);
+}
+int SandboxedVfsRandomness(sqlite3_vfs* vfs, int result_size, char* result) {
+ return SandboxedVfsFromSqliteVfs(vfs)->Randomness(result_size, result);
+}
+int SandboxedVfsSleep(sqlite3_vfs* vfs, int microseconds) {
+ return SandboxedVfsFromSqliteVfs(vfs)->Sleep(microseconds);
+}
+int SandboxedVfsGetLastError(sqlite3_vfs* vfs,
+ int message_size,
+ char* message) {
+ return SandboxedVfsFromSqliteVfs(vfs)->GetLastError(message_size, message);
+}
+int SandboxedVfsCurrentTimeInt64(sqlite3_vfs* vfs, sqlite3_int64* result_ms) {
+ return SandboxedVfsFromSqliteVfs(vfs)->CurrentTimeInt64(result_ms);
+}
+
+sqlite3_vfs SqliteVfsFor(SandboxedVfs* sandboxed_vfs) {
+ DCHECK_EQ(sandboxed_vfs, reinterpret_cast<SandboxedVfs*>(
+ reinterpret_cast<void*>(sandboxed_vfs)))
+ << "This implementation round-trips SandboxedVfs* via void*";
+
+ // VFS API entry points are listed at https://www.sqlite.org/c3ref/vfs.html
+ static constexpr int kSqliteVfsApiVersion = 3;
+
+ // Maximum file path size.
+ // TODO(pwnall): Obtain this from //base or some other good place.
+ static constexpr int kSqliteMaxPathSize = 512;
+
+ return {
+ kSqliteVfsApiVersion,
+ sizeof(SandboxedVfsFileSqliteBridge),
+ kSqliteMaxPathSize,
+ /*pNext=*/nullptr,
+ kSqliteVfsName,
+ /*pAppData=*/reinterpret_cast<void*>(sandboxed_vfs),
+ SandboxedVfsOpen,
+ SandboxedVfsDelete,
+ SandboxedVfsAccess,
+ SandboxedVfsFullPathname,
+ /*xDlOpen=*/nullptr,
+ /*xDlError=*/nullptr,
+ /*xDlSym=*/nullptr,
+ /*xDlClose=*/nullptr,
+ SandboxedVfsRandomness,
+ SandboxedVfsSleep,
+ /*xCurrentTime=*/nullptr, // Deprecated in API versions 2 and above.
+ SandboxedVfsGetLastError,
+ SandboxedVfsCurrentTimeInt64,
+ /*xSetSystemCall=*/nullptr,
+ /*xGetSystemCall=*/nullptr,
+ /*xNextSystemCall=*/nullptr,
+ };
+}
+
+// Converts a SQLite full file path to a Blink string.
+//
+// The argument is guaranteed to be the result of a FullPathname() call, with
+// an optional suffix. The suffix always starts with "-".
+String StringFromFullPath(const char* full_path) {
+ DCHECK(full_path);
+ return String::FromUTF8(full_path);
+}
+
+// SQLite measures time according to the Julian calendar.
+WTF::Time SqliteEpoch() {
+ constexpr const double kMicroSecondsPerDay = 24 * 60 * 60 * 1000;
+ // The ".5" is intentional -- days in the Julian calendar start at noon.
+ // The offset is in the SQLite source code (os_unix.c) multiplied by 10.
+ constexpr const double kUnixEpochAsJulianDay = 2440587.5;
+
+ return WTF::Time::FromJsTime(-kUnixEpochAsJulianDay * kMicroSecondsPerDay);
+}
+
+} // namespace
+
+// static
+SandboxedVfs& SandboxedVfs::GetInstance() {
+ DEFINE_THREAD_SAFE_STATIC_LOCAL(SandboxedVfs, instance, ());
+ return instance;
+}
+
+SandboxedVfs::SandboxedVfs()
+ : sandboxed_vfs_(SqliteVfsFor(this)),
+ sqlite_epoch_(SqliteEpoch()),
+ platform_(Platform::Current()),
+ last_error_(base::File::FILE_OK) {
+ sql::EnsureSqliteInitialized();
+
+ // The register function returns a SQLite status as an int. The status is
+ // ignored here. If registration fails, we'd want to report the error while
+ // attempting to open a database. This is exactly what will happen, because
+ // SQLite won't find the VFS we're asking for.
+ sqlite3_vfs_register(&sandboxed_vfs_, /*make_default=*/0);
+}
+
+std::tuple<int, sqlite3*> SandboxedVfs::OpenDatabase(const String& filename) {
+ sqlite3* connection;
+ constexpr int open_flags =
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE;
+ int status = sqlite3_open_v2(filename.Utf8().data(), &connection, open_flags,
+ kSqliteVfsName);
+ if (status != SQLITE_OK) {
+ // SQLite creates a connection handle in most cases where open fails.
+ if (connection) {
+ sqlite3_close(connection);
+ connection = nullptr;
+ }
+ }
+ return {status, connection};
+}
+
+int SandboxedVfs::Open(const char* full_path,
+ sqlite3_file* result_file,
+ int requested_flags,
+ int* granted_flags) {
+ DCHECK(full_path) << "WebSQL does not support creating temporary file names";
+ DCHECK(result_file);
+ DCHECK_EQ(0, requested_flags & SQLITE_OPEN_DELETEONCLOSE)
+ << "SQLITE_OPEN_DELETEONCLOSE should not be used by WebSQL";
+ DCHECK_EQ(0, requested_flags & SQLITE_OPEN_EXCLUSIVE)
+ << "SQLITE_OPEN_EXCLUSIVE should not be used by WebSQL";
+
+ String file_name = StringFromFullPath(full_path);
+
+ // TODO(pwnall): This doesn't have to be synchronous. WebSQL's open sequence
+ // is asynchronous, so we could open all the needed files (DB,
+ // journal, etc.) asynchronously, and store them in a hash table
+ // that would be used here.
+ base::File file = platform_->DatabaseOpenFile(file_name, requested_flags);
+
+ if (!file.IsValid()) {
+ // TODO(pwnall): Figure out if we can remove the fallback to read-only.
+ if (!(requested_flags & SQLITE_OPEN_READWRITE)) {
+ // The SQLite API requires that pMethods is set to null even if the open
+ // call returns a failure status.
+ result_file->pMethods = nullptr;
+ return SQLITE_CANTOPEN;
+ }
+
+ int new_flags =
+ (requested_flags & ~SQLITE_OPEN_READWRITE) | SQLITE_OPEN_READONLY;
+ return Open(full_path, result_file, new_flags, granted_flags);
+ }
+
+ SandboxedVfsFile::Create(std::move(file), std::move(file_name), this,
+ result_file);
+ if (granted_flags)
+ *granted_flags = requested_flags;
+ return SQLITE_OK;
+}
+
+int SandboxedVfs::Delete(const char* full_path, int sync_dir) {
+ DCHECK(full_path);
+ return platform_->DatabaseDeleteFile(StringFromFullPath(full_path), sync_dir);
+}
+
+int SandboxedVfs::Access(const char* full_path, int flags, int* result) {
+ DCHECK(full_path);
+ DCHECK(result);
+ long attributes =
+ platform_->DatabaseGetFileAttributes(StringFromFullPath(full_path));
+
+ // TODO(pwnall): Make the mojo interface portable across OSes, instead of
+ // messing around with OS-dependent constants here.
+
+#if defined(OS_WIN)
+ const bool file_exists =
+ static_cast<DWORD>(attributes) != INVALID_FILE_ATTRIBUTES;
+#else
+ const bool file_exists = attributes >= 0;
+#endif // defined(OS_WIN)
+
+ if (!file_exists) {
+ *result = 0;
+ return SQLITE_OK;
+ }
+
+#if defined(OS_WIN)
+ const bool can_read = true;
+ const bool can_write = (attributes & FILE_ATTRIBUTE_READONLY) == 0;
+#else
+ const bool can_read = (attributes & R_OK) != 0;
+ const bool can_write = (attributes & W_OK) != 0;
+#endif // defined(OS_WIN)
+
+ switch (flags) {
+ case SQLITE_ACCESS_EXISTS:
+ *result = 1;
+ break;
+ case SQLITE_ACCESS_READ:
+ *result = can_read ? 1 : 0;
+ break;
+ case SQLITE_ACCESS_READWRITE:
+ *result = (can_read && can_write) ? 1 : 0;
+ break;
+ default:
+ NOTREACHED() << "Unsupported xAccess flags: " << flags;
+ return SQLITE_ERROR;
+ }
+ return SQLITE_OK;
+}
+
+int SandboxedVfs::FullPathname(const char* file_path,
+ int result_size,
+ char* result) {
+ DCHECK(file_path);
+ DCHECK_GT(result_size, 0);
+ DCHECK(result);
+
+ // Renderer processes cannot access files directly, so it doesn't make sense
+ // to expose full paths here.
+ size_t file_path_size = std::strlen(file_path) + 1;
+ if (static_cast<size_t>(result_size) < file_path_size)
+ return SQLITE_CANTOPEN;
+ std::memcpy(result, file_path, file_path_size);
+ return SQLITE_OK;
+}
+
+int SandboxedVfs::Randomness(int result_size, char* result) {
+ DCHECK_GT(result_size, 0);
+ DCHECK(result);
+
+ // TODO(pwnall): Figure out if we need a real implementation.
+ std::memset(result, 0, result_size);
+ return result_size;
+}
+
+int SandboxedVfs::Sleep(int microseconds) {
+ DCHECK_GE(microseconds, 0);
+ base::PlatformThread::Sleep(WTF::TimeDelta::FromMicroseconds(microseconds));
+ return SQLITE_OK;
+}
+
+int SandboxedVfs::GetLastError(int message_size, char* message) const {
+ DCHECK_GE(message_size, 0);
+ DCHECK(message_size == 0 || message);
+
+ std::string error_string = base::File::ErrorToString(last_error_);
+ size_t error_string_size = error_string.length() + 1;
+ size_t copy_length =
+ std::min(static_cast<size_t>(message_size), error_string_size);
+ std::memcpy(message, error_string.c_str(), copy_length);
+ // The return value is zero if the message fits in the buffer, and non-zero if
+ // it does not fit.
+ return copy_length != error_string_size;
+}
+
+int SandboxedVfs::CurrentTimeInt64(sqlite3_int64* result_ms) {
+ DCHECK(result_ms);
+
+ WTF::TimeDelta delta = WTF::Time::Now() - sqlite_epoch_;
+ *result_ms = delta.InMilliseconds();
+ return SQLITE_OK;
+}
+
+} // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h
new file mode 100644
index 0000000..366ade9e
--- /dev/null
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h
@@ -0,0 +1,71 @@
+// Copyright 2019 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_H_
+
+#include <tuple>
+
+#include "base/files/file.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/time.h"
+#include "third_party/sqlite/sqlite3.h"
+
+namespace blink {
+
+class Platform;
+
+// SQLite VFS implementation that works in the Chrome renderer sandbox.
+//
+// Instances are thread-friendly, and expected to be used on Blink's database
+// thread.
+class SandboxedVfs {
+ USING_FAST_MALLOC(SandboxedVfs);
+
+ public:
+ // Factory method for the singleton instance.
+ static SandboxedVfs& GetInstance();
+
+ ~SandboxedVfs() = delete;
+
+ // Opens a database file.
+ //
+ // Returns a SQLite status and a SQLite connection. If the status is not
+ // SQLITE_OK, the returned connection is null.
+ std::tuple<int, sqlite3*> OpenDatabase(const String& filename);
+
+ // sqlite3_vfs implementation.
+ int Open(const char* full_path,
+ sqlite3_file* result_file,
+ int requested_flags,
+ int* granted_flags);
+ int Delete(const char* full_path, int sync_dir);
+ int Access(const char* full_path, int flags, int* result);
+ int FullPathname(const char* file_path, int result_size, char* result);
+ int Randomness(int result_size, char* result);
+ int Sleep(int microseconds);
+ int GetLastError(int message_size, char* message) const;
+ int CurrentTimeInt64(sqlite3_int64* result_ms);
+
+ // Used by SandboxedVfsFile.
+ Platform* GetPlatform() { return platform_; }
+ void SetLastError(base::File::Error error) { this->last_error_ = error; }
+
+ private:
+ // Use GetInstance() instead of constructing this directly.
+ SandboxedVfs();
+
+ // Registers the VFS with SQLite. Failures are silently ignored.
+ void RegisterVfs();
+
+ sqlite3_vfs sandboxed_vfs_;
+ const WTF::Time sqlite_epoch_;
+ Platform* const platform_;
+ base::File::Error last_error_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_H_
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc
new file mode 100644
index 0000000..2fd7f1815
--- /dev/null
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc
@@ -0,0 +1,532 @@
+// Copyright 2019 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 "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h"
+
+#include <atomic>
+#include <cstring>
+#include <type_traits>
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/logging.h"
+#include "base/threading/platform_thread.h"
+#include "build/build_config.h"
+#include "sql/initialization.h"
+#include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h"
+#include "third_party/sqlite/sqlite3.h"
+
+namespace blink {
+
+namespace {
+
+int SandboxedClose(sqlite3_file* file) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Close();
+}
+int SandboxedRead(sqlite3_file* file,
+ void* buffer,
+ int size,
+ sqlite3_int64 offset) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Read(buffer, size, offset);
+}
+int SandboxedWrite(sqlite3_file* file,
+ const void* buffer,
+ int size,
+ sqlite3_int64 offset) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Write(buffer, size, offset);
+}
+int SandboxedTruncate(sqlite3_file* file, sqlite3_int64 size) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Truncate(size);
+}
+int SandboxedSync(sqlite3_file* file, int flags) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Sync(flags);
+}
+int SandboxedFileSize(sqlite3_file* file, sqlite3_int64* result_size) {
+ return SandboxedVfsFile::FromSqliteFile(file)->FileSize(result_size);
+}
+int SandboxedLock(sqlite3_file* file, int mode) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Lock(mode);
+}
+int SandboxedUnlock(sqlite3_file* file, int mode) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Unlock(mode);
+}
+int SandboxedCheckReservedLock(sqlite3_file* file, int* has_reserved_lock) {
+ return SandboxedVfsFile::FromSqliteFile(file)->CheckReservedLock(
+ has_reserved_lock);
+}
+int SandboxedFileControl(sqlite3_file* file, int opcode, void* data) {
+ return SandboxedVfsFile::FromSqliteFile(file)->FileControl(opcode, data);
+}
+int SandboxedSectorSize(sqlite3_file* file) {
+ return SandboxedVfsFile::FromSqliteFile(file)->SectorSize();
+}
+int SandboxedDeviceCharacteristics(sqlite3_file* file) {
+ return SandboxedVfsFile::FromSqliteFile(file)->DeviceCharacteristics();
+}
+int SandboxedShmMap(sqlite3_file* file,
+ int page_index,
+ int page_size,
+ int extend_file_if_needed,
+ void volatile** result) {
+ return SandboxedVfsFile::FromSqliteFile(file)->ShmMap(
+ page_index, page_size, extend_file_if_needed, result);
+}
+int SandboxedShmLock(sqlite3_file* file, int offset, int size, int flags) {
+ return SandboxedVfsFile::FromSqliteFile(file)->ShmLock(offset, size, flags);
+}
+void SandboxedShmBarrier(sqlite3_file* file) {
+ SandboxedVfsFile::FromSqliteFile(file)->ShmBarrier();
+}
+int SandboxedShmUnmap(sqlite3_file* file, int also_delete_file) {
+ return SandboxedVfsFile::FromSqliteFile(file)->ShmUnmap(also_delete_file);
+}
+int SandboxedFetch(sqlite3_file* file,
+ sqlite3_int64 offset,
+ int size,
+ void** result) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Fetch(offset, size, result);
+}
+int SandboxedUnfetch(sqlite3_file* file,
+ sqlite3_int64 offset,
+ void* fetch_result) {
+ return SandboxedVfsFile::FromSqliteFile(file)->Unfetch(offset, fetch_result);
+}
+
+const sqlite3_io_methods* GetSqliteIoMethods() {
+ // VFS IO API entry points are listed at
+ // https://www.sqlite.org/c3ref/io_methods.html
+ static constexpr int kSqliteVfsIoApiVersion = 3;
+
+ static const sqlite3_io_methods kIoMethods = {
+ kSqliteVfsIoApiVersion,
+ SandboxedClose,
+ SandboxedRead,
+ SandboxedWrite,
+ SandboxedTruncate,
+ SandboxedSync,
+ SandboxedFileSize,
+ SandboxedLock,
+ SandboxedUnlock,
+ SandboxedCheckReservedLock,
+ SandboxedFileControl,
+ SandboxedSectorSize,
+ SandboxedDeviceCharacteristics,
+ SandboxedShmMap,
+ SandboxedShmLock,
+ SandboxedShmBarrier,
+ SandboxedShmUnmap,
+ SandboxedFetch,
+ SandboxedUnfetch,
+ };
+
+ return &kIoMethods;
+}
+
+} // namespace
+
+// static
+void SandboxedVfsFile::Create(base::File file,
+ String file_name,
+ SandboxedVfs* vfs,
+ sqlite3_file* buffer) {
+ SandboxedVfsFileSqliteBridge* bridge =
+ SandboxedVfsFileSqliteBridge::FromSqliteFile(buffer);
+ bridge->blink_file =
+ new SandboxedVfsFile(std::move(file), std::move(file_name), vfs);
+ bridge->sqlite_file.pMethods = GetSqliteIoMethods();
+}
+
+// static
+SandboxedVfsFile* SandboxedVfsFile::FromSqliteFile(sqlite3_file* sqlite_file) {
+ return SandboxedVfsFileSqliteBridge::FromSqliteFile(sqlite_file)->blink_file;
+}
+
+int SandboxedVfsFile::Close() {
+ file_.Close();
+ return SQLITE_OK;
+}
+
+int SandboxedVfsFile::Read(void* buffer, int size, sqlite3_int64 offset) {
+ DCHECK(buffer);
+ DCHECK_GE(size, 0);
+ DCHECK_GE(offset, 0);
+ char* data = reinterpret_cast<char*>(buffer);
+
+ // If we supported mmap()ed files, we'd check for a memory mapping here,
+ // and try to fill as much of the request as possible from the mmap()ed
+ // region.
+
+ int bytes_read = file_.Read(offset, data, size);
+ DCHECK_LE(bytes_read, size);
+ if (bytes_read == size)
+ return SQLITE_OK;
+
+ // SQLite first reads the database header without locking the file. On
+ // Windows, this read will fail if there is an exclusive lock on the file,
+ // even if the current process owns that lock.
+ if (sqlite_lock_mode_ == SQLITE_LOCK_NONE) {
+ // The unlocked read is considered an optimization. SQLite can continue even
+ // if the read fails, as long as failure is communicated by zeroing out the
+ // output buffer.
+ std::memset(data, 0, size);
+ return SQLITE_OK;
+ }
+
+ if (bytes_read < 0) {
+ vfs_->SetLastError(base::File::GetLastFileError());
+ return SQLITE_IOERR_READ;
+ }
+
+ // SQLite requires that we fill the unread bytes in the buffer with zeros.
+ std::memset(data + bytes_read, 0, size - bytes_read);
+ return SQLITE_IOERR_SHORT_READ;
+}
+
+int SandboxedVfsFile::Write(const void* buffer,
+ int size,
+ sqlite3_int64 offset) {
+ DCHECK(buffer);
+ DCHECK_GE(size, 0);
+ DCHECK_GE(offset, 0);
+ const char* data = reinterpret_cast<const char*>(buffer);
+
+ // If we supported mmap()ed files, we'd check for a memory mapping here,
+ // and try to fill as much of the request as possible by copying to the
+ // mmap()ed region.
+
+ int bytes_written = file_.Write(offset, data, size);
+ DCHECK_LE(bytes_written, size);
+ if (bytes_written >= size)
+ return SQLITE_OK;
+
+ base::File::Error last_error = base::File::GetLastFileError();
+ vfs_->SetLastError(last_error);
+ if (last_error == base::File::Error::FILE_ERROR_NO_SPACE)
+ return SQLITE_FULL;
+
+ return SQLITE_IOERR_WRITE;
+}
+
+int SandboxedVfsFile::Truncate(sqlite3_int64 size) {
+ if (file_.SetLength(size))
+ return SQLITE_OK;
+
+ // On Mac and Linux, the renderer sandbox blocks ftruncate(), so we have to
+ // use a sync mojo IPC to ask the browser process to call ftruncate() for us.
+ //
+ // TODO(pwnall): Figure out if we can allow ftruncate() in the renderer. It
+ // would be useful for low-level storage APIs, like the upcoming
+ // filesystem API.
+ if (!vfs_->GetPlatform()->DatabaseSetFileSize(file_name_, size))
+ return SQLITE_IOERR_TRUNCATE;
+
+ return SQLITE_OK;
+}
+
+int SandboxedVfsFile::Sync(int flags) {
+ // NOTE: SQLite passes in (SQLITE_SYNC_NORMAL or SQLITE_SYNC_FULL),
+ // potentially OR-ed with SQLITE_SYNC_DATAONLY. Implementing these could
+ // lead to better performance.
+ if (!file_.Flush()) {
+ vfs_->SetLastError(base::File::GetLastFileError());
+ return SQLITE_IOERR_FSYNC;
+ }
+
+ // The unix VFS also syncs the file's directory on the first xSync() call.
+ // Chrome's LevelDB Env implementation does the same for specific files
+ // (database manifests).
+ //
+ // For WebSQL, we would want to sync the directory at file open time, when the
+ // file is opened for writing.
+
+ return SQLITE_OK;
+}
+
+int SandboxedVfsFile::FileSize(sqlite3_int64* result_size) {
+ int64_t length = file_.GetLength();
+ if (length < 0) {
+ vfs_->SetLastError(base::File::GetLastFileError());
+ return SQLITE_IOERR_FSTAT;
+ }
+
+ // SQLite's unix VFS reports 1-byte files as empty. This is documented as a
+ // workaround for a fairly obscure bug. See unixFileSize() in os_unix.c.
+ if (length == 1)
+ length = 0;
+
+ *result_size = length;
+ return SQLITE_OK;
+}
+
+namespace {
+
+// True if our simplified implementation uses an exclusive lock for a mode.
+bool IsExclusiveLockMode(int sqlite_lock_mode) {
+ switch (sqlite_lock_mode) {
+ case SQLITE_LOCK_NONE:
+ case SQLITE_LOCK_SHARED:
+ return false;
+
+ case SQLITE_LOCK_RESERVED:
+ case SQLITE_LOCK_PENDING:
+ case SQLITE_LOCK_EXCLUSIVE:
+ return true;
+ }
+
+ NOTREACHED() << "Unsupported mode: " << sqlite_lock_mode;
+ return false;
+}
+
+} // namespace
+
+int SandboxedVfsFile::Lock(int mode) {
+#if defined(OS_FUCHSIA)
+ return SQLITE_IOERR_LOCK;
+#else
+ base::File::LockMode file_lock_mode = base::File::LockMode::kExclusive;
+
+ switch (mode) {
+ case SQLITE_LOCK_NONE:
+ return SQLITE_OK;
+
+ case SQLITE_LOCK_SHARED:
+ if (sqlite_lock_mode_ != SQLITE_LOCK_NONE)
+ return SQLITE_OK;
+
+ file_lock_mode = base::File::LockMode::kShared;
+ break;
+
+ case SQLITE_LOCK_RESERVED:
+ // A SHARED lock is required before a RESERVED lock is acquired.
+ DCHECK_EQ(sqlite_lock_mode_, SQLITE_LOCK_SHARED);
+ file_lock_mode = base::File::LockMode::kExclusive;
+ break;
+
+ case SQLITE_LOCK_PENDING:
+ // A SHARED lock is required before a PENDING lock is acquired. The caller
+ // may have a RESERVED lock.
+ if (sqlite_lock_mode_ == SQLITE_LOCK_RESERVED) {
+ sqlite_lock_mode_ = mode;
+ return SQLITE_OK;
+ }
+
+ DCHECK_EQ(sqlite_lock_mode_, SQLITE_LOCK_SHARED);
+ file_lock_mode = base::File::LockMode::kExclusive;
+ break;
+
+ case SQLITE_LOCK_EXCLUSIVE:
+ if (IsExclusiveLockMode(sqlite_lock_mode_)) {
+ sqlite_lock_mode_ = mode;
+ return SQLITE_OK;
+ }
+ file_lock_mode = base::File::LockMode::kExclusive;
+ break;
+
+ default:
+ NOTREACHED() << "Unimplemented xLock() mode: " << mode;
+ }
+
+ DCHECK_EQ(IsExclusiveLockMode(mode),
+ file_lock_mode == base::File::LockMode::kExclusive)
+ << "Incorrect file_lock_mode logic for SQLite mode: " << mode;
+
+ // On POSIX, it would be possible to upgrade atomically from a shared lock to
+ // an exclusive lock. This implementation prioritizes the simplicity of no
+ // platform-specific code over being faster in high contention cases.
+ if (sqlite_lock_mode_ != SQLITE_LOCK_NONE) {
+ base::File::Error error = file_.Unlock();
+ if (error != base::File::FILE_OK) {
+ vfs_->SetLastError(base::File::GetLastFileError());
+ return SQLITE_IOERR_LOCK;
+ }
+ sqlite_lock_mode_ = SQLITE_LOCK_NONE;
+ }
+
+ base::File::Error error = file_.Lock(file_lock_mode);
+ if (error != base::File::FILE_OK) {
+ vfs_->SetLastError(base::File::GetLastFileError());
+ return SQLITE_IOERR_LOCK;
+ }
+
+ sqlite_lock_mode_ = mode;
+ return SQLITE_OK;
+#endif // defined(OS_FUCHSIA)
+}
+
+int SandboxedVfsFile::Unlock(int mode) {
+ // No-op if we're already unlocked or at the requested mode.
+ if (sqlite_lock_mode_ == mode || sqlite_lock_mode_ == SQLITE_LOCK_NONE)
+ return SQLITE_OK;
+
+#if defined(OS_FUCHSIA)
+ return SQLITE_IOERR_UNLOCK;
+#else
+ // On POSIX, it is possible to downgrade atomically from an exclusive lock to
+ // a shared lock. SQLite's unix VFS takes advantage of this. This
+ // implementation prioritizes the simplicity of no platform-specific code over
+ // being faster in high contention cases.
+ base::File::Error error = file_.Unlock();
+ if (error != base::File::FILE_OK) {
+ vfs_->SetLastError(base::File::GetLastFileError());
+ return SQLITE_IOERR_UNLOCK;
+ }
+
+ if (mode == SQLITE_LOCK_NONE) {
+ sqlite_lock_mode_ = mode;
+ return SQLITE_OK;
+ }
+
+ DCHECK_EQ(mode, SQLITE_LOCK_SHARED);
+ error = file_.Lock(base::File::LockMode::kShared);
+ if (error == base::File::FILE_OK) {
+ sqlite_lock_mode_ = mode;
+ return SQLITE_OK;
+ }
+
+ // Gave up the exclusive lock, but failed to get a shared lock.
+ vfs_->SetLastError(base::File::GetLastFileError());
+ sqlite_lock_mode_ = SQLITE_LOCK_NONE;
+ return SQLITE_IOERR_UNLOCK;
+#endif // defined(OS_FUCHSIA)
+}
+
+int SandboxedVfsFile::CheckReservedLock(int* has_reserved_lock) {
+ if (IsExclusiveLockMode(sqlite_lock_mode_)) {
+ *has_reserved_lock = 1;
+ return SQLITE_OK;
+ }
+
+ if (sqlite_lock_mode_ == SQLITE_LOCK_SHARED) {
+ // Lock modes at or above RESERVED map to exclusive locks in our simplified
+ // implementation. If this process has a shared lock, no other process can
+ // have an exclusive lock.
+ *has_reserved_lock = 0;
+ return SQLITE_OK;
+ }
+
+#if defined(OS_FUCHSIA)
+ return SQLITE_IOERR_CHECKRESERVEDLOCK;
+#else
+ // On POSIX, it's possible to query the existing lock state of a file. The
+ // SQLite unix VFS takes advantage of this. On Windows, this isn't the case.
+ // Follow the strategy of the Windows VFS, which checks by trying to get an
+ // exclusive lock on the file.
+ base::File::Error error = file_.Lock(base::File::LockMode::kShared);
+ if (error != base::File::FILE_OK) {
+ *has_reserved_lock = 1;
+ return SQLITE_OK;
+ }
+
+ *has_reserved_lock = 0;
+ if (file_.Unlock() == base::File::FILE_OK)
+ return SQLITE_OK;
+
+ // We acquired a shared lock that we can't get rid of.
+ sqlite_lock_mode_ = SQLITE_LOCK_SHARED;
+ return SQLITE_IOERR_CHECKRESERVEDLOCK;
+#endif // defined(OS_FUCHSIA)
+}
+
+int SandboxedVfsFile::FileControl(int opcode, void* data) {
+ switch (opcode) {
+ case SQLITE_FCNTL_MMAP_SIZE:
+ // Implementing memory-mapping will require handling this correctly.
+ return SQLITE_NOTFOUND;
+ default:
+ return SQLITE_NOTFOUND;
+ }
+}
+
+int SandboxedVfsFile::SectorSize() {
+ return 0;
+}
+
+int SandboxedVfsFile::DeviceCharacteristics() {
+ // TODO(pwnall): Figure out if we can get away with returning 0 on Windows.
+#if defined(OS_WIN)
+ return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
+#else
+ // NOTE: SQLite's unix VFS attempts to detect the underlying filesystem and
+ // sets some flags based on the result.
+ return 0;
+#endif // OS_WIN
+}
+
+int SandboxedVfsFile::ShmMap(int page_index,
+ int page_size,
+ int extend_file_if_needed,
+ void volatile** result) {
+ DCHECK_GE(page_index, 0);
+ DCHECK_GE(page_size, 0);
+ DCHECK(result);
+
+ // NOTE: This would be needed by SQLite's WAL mode.
+ *result = nullptr;
+ return SQLITE_IOERR;
+}
+
+int SandboxedVfsFile::ShmLock(int offset, int size, int flags) {
+ DCHECK_GE(offset, 0);
+ DCHECK_GE(size, 0);
+
+ // NOTE: This would be needed by SQLite's WAL mode.
+ return SQLITE_IOERR;
+}
+
+void SandboxedVfsFile::ShmBarrier() {
+ // All writes to shared memory that have already been issued before this
+ // function is called must complete before the function returns.
+ std::atomic_thread_fence(std::memory_order_acq_rel);
+}
+
+int SandboxedVfsFile::ShmUnmap(int also_delete_file) {
+ // NOTE: This would be needed by SQLite's WAL mode.
+ return SQLITE_IOERR;
+}
+
+int SandboxedVfsFile::Fetch(sqlite3_int64 offset, int size, void** result) {
+ DCHECK_GE(offset, 0);
+ DCHECK_GE(size, 0);
+ DCHECK(result);
+
+ // NOTE: This would be needed for mmap()ed file support.
+ *result = nullptr;
+ return SQLITE_IOERR;
+}
+
+int SandboxedVfsFile::Unfetch(sqlite3_int64 offset, void* fetch_result) {
+ DCHECK_GE(offset, 0);
+ DCHECK(fetch_result);
+
+ // NOTE: This would be needed for mmap()ed file support.
+ return SQLITE_IOERR;
+}
+
+SandboxedVfsFile::SandboxedVfsFile(base::File file,
+ String file_name,
+ SandboxedVfs* vfs)
+ : file_(std::move(file)),
+ sqlite_lock_mode_(SQLITE_LOCK_NONE),
+ vfs_(vfs),
+ file_name_(std::move(file_name)) {}
+
+SandboxedVfsFile::~SandboxedVfsFile() = default;
+
+// static
+SandboxedVfsFileSqliteBridge* SandboxedVfsFileSqliteBridge::FromSqliteFile(
+ sqlite3_file* sqlite_file) {
+ static_assert(std::is_standard_layout<SandboxedVfsFileSqliteBridge>::value,
+ "needed for the reinterpret_cast below");
+ static_assert(offsetof(SandboxedVfsFileSqliteBridge, sqlite_file) == 0,
+ "sqlite_file must be the first member of the struct.");
+
+ SandboxedVfsFileSqliteBridge* bridge =
+ reinterpret_cast<SandboxedVfsFileSqliteBridge*>(sqlite_file);
+ DCHECK_EQ(sqlite_file, &bridge->sqlite_file)
+ << "assumed by the reinterpret_casts in the implementation";
+ return bridge;
+}
+
+} // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h
new file mode 100644
index 0000000..a0e76ac
--- /dev/null
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h
@@ -0,0 +1,95 @@
+// Copyright 2019 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.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_FILE_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_FILE_H_
+
+#include "base/files/file.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/sqlite/sqlite3.h"
+
+namespace blink {
+
+class SandboxedVfs;
+class SandboxedVfsFile;
+
+// SQLite VFS file implementation that works in the Chrome renderer sandbox.
+//
+// An instance is created when SQLite calls into SandboxedVfs::Open(). The
+// instance is deleted by a call to SandboxedVfsFile::Close().
+//
+// The SQLite VFS API includes a complex locking strategy documented in
+// https://www.sqlite.org/lockingv3.html
+//
+// This implementation uses a simplified locking strategy, where we grab an
+// exclusive lock when entering any of the modes that prepare for a transition
+// to EXCLUSIVE. (These modes are RESERVED and PENDING). This approach is easy
+// to implement on top of base::File's locking primitives, at the cost of some
+// false contention, which makes us slower under high concurrency.
+//
+// SQLite's built-in VFSes use the OS support for locking a range of bytes in
+// the file, rather locking than the whole file.
+class SandboxedVfsFile {
+ USING_FAST_MALLOC(SandboxedVfsFile);
+
+ public:
+ // Creates an instance in the given buffer.
+ static void Create(base::File file,
+ String file_name,
+ SandboxedVfs* vfs,
+ sqlite3_file* buffer);
+
+ // Extracts the instance bridged to the given SQLite VFS file.
+ static SandboxedVfsFile* FromSqliteFile(sqlite3_file* sqlite_file);
+
+ // sqlite3_file implementation.
+ int Close();
+ int Read(void* buffer, int size, sqlite3_int64 offset);
+ int Write(const void* buffer, int size, sqlite3_int64 offset);
+ int Truncate(sqlite3_int64 size);
+ int Sync(int flags);
+ int FileSize(sqlite3_int64* result_size);
+ int Lock(int mode);
+ int Unlock(int mode);
+ int CheckReservedLock(int* has_reserved_lock);
+ int FileControl(int opcode, void* data);
+ int SectorSize();
+ int DeviceCharacteristics();
+ int ShmMap(int page_index,
+ int page_size,
+ int extend_file_if_needed,
+ void volatile** result);
+ int ShmLock(int offset, int size, int flags);
+ void ShmBarrier();
+ int ShmUnmap(int also_delete_file);
+ int Fetch(sqlite3_int64 offset, int size, void** result);
+ int Unfetch(sqlite3_int64 offset, void* fetch_result);
+
+ private:
+ SandboxedVfsFile(base::File file, String file_name, SandboxedVfs* vfs);
+ ~SandboxedVfsFile();
+
+ // Constructed from a file handle passed from the browser process.
+ base::File file_;
+ // One of the SQLite locking mode constants.
+ int sqlite_lock_mode_;
+ // The SandboxedVfs that created this instance.
+ SandboxedVfs* const vfs_;
+ // Used to identify the file in IPCs to the browser process.
+ const String file_name_;
+};
+
+// sqlite3_file "subclass" that bridges to a SandboxedVfsFile instance.
+struct SandboxedVfsFileSqliteBridge {
+ sqlite3_file sqlite_file;
+ SandboxedVfsFile* blink_file;
+
+ static SandboxedVfsFileSqliteBridge* FromSqliteFile(
+ sqlite3_file* sqlite_file);
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_FILE_H_
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
index c442185a..674ef3a8 100644
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
+++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
@@ -27,8 +27,8 @@
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h"
#include "third_party/blink/renderer/modules/webdatabase/database_authorizer.h"
+#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h"
-#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.h"
#include "third_party/sqlite/sqlite3.h"
@@ -60,14 +60,15 @@
bool SQLiteDatabase::Open(const String& filename) {
Close();
- open_error_ = SQLiteFileSystem::OpenDatabase(filename, &db_);
+ std::tie(open_error_, db_) =
+ SandboxedVfs::GetInstance().OpenDatabase(filename);
if (open_error_ != SQLITE_OK) {
+ DCHECK_EQ(db_, nullptr);
+
open_error_message_ =
db_ ? sqlite3_errmsg(db_) : "sqlite_open returned null";
DLOG(ERROR) << "SQLite database failed to load from " << filename
<< "\nCause - " << open_error_message_.data();
- sqlite3_close(db_);
- db_ = nullptr;
return false;
}
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
deleted file mode 100644
index ed1d1ab..0000000
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
-
-#include "sql/initialization.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/wtf/text/cstring.h"
-#include "third_party/sqlite/sqlite3.h"
-
-// SQLiteFileSystem::registerSQLiteVFS() is implemented in the
-// platform-specific files SQLiteFileSystemChromium{Win|Posix}.cpp
-namespace blink {
-
-#if DCHECK_IS_ON()
-// static
-bool SQLiteFileSystem::initialize_sqlite_called_ = false;
-#endif // DCHECK_IS_ON
-
-// static
-void SQLiteFileSystem::InitializeSQLite() {
-#if DCHECK_IS_ON()
- DCHECK(!initialize_sqlite_called_) << __func__ << " already called";
- initialize_sqlite_called_ = true;
-#endif // DCHECK_IS_ON()
-
- sql::EnsureSqliteInitialized();
- RegisterSQLiteVFS();
-}
-
-// static
-int SQLiteFileSystem::OpenDatabase(const String& filename, sqlite3** database) {
-#if DCHECK_IS_ON()
- DCHECK(initialize_sqlite_called_)
- << "InitializeSQLite() must be called before " << __func__;
-#endif // DCHECK_IS_ON()
-
- return sqlite3_open_v2(
- filename.Utf8().data(), database,
- SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE,
- "chromium_vfs");
-}
-
-} // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h
deleted file mode 100644
index a4fc984..0000000
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SQLITE_FILE_SYSTEM_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SQLITE_FILE_SYSTEM_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-#include "third_party/blink/renderer/platform/wtf/threading.h"
-
-struct sqlite3;
-
-namespace blink {
-
-// A class that abstracts the file system related operations required
-// by the WebKit database code.
-class SQLiteFileSystem {
- STATIC_ONLY(SQLiteFileSystem);
-
- public:
- // Initializes SQLite for Blink's use.
- //
- // This must be called exactly once in each renderer process that uses SQLite.
- static void InitializeSQLite();
-
- // Opens a database file.
- //
- // InitializeSQLite() must be called before this method is called.
- //
- // filename - The name of the database file.
- // database - The SQLite structure that represents the database stored
- // in the given file.
- static int OpenDatabase(const String& filename, sqlite3** database);
-
- private:
- // Registers Chromium's VFS with SQLite.
- static void RegisterSQLiteVFS();
-
-#if DCHECK_IS_ON()
- static bool initialize_sqlite_called_;
-#endif // DCHECK_IS_ON()
-}; // class SQLiteFileSystem
-
-} // namespace blink
-
-#endif
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc
deleted file mode 100644
index 88113bc..0000000
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_posix.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/sqlite/sqlite3.h"
-
-namespace blink {
-
-// Chromium's Posix implementation of SQLite VFS
-namespace {
-
-struct chromiumVfsFile {
- sqlite3_io_methods* p_methods;
- sqlite3_file* wrapped_file;
- char* wrapped_file_name;
-};
-
-int ChromiumClose(sqlite3_file* sqlite_file) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- int r = chromium_file->wrapped_file->pMethods->xClose(
- chromium_file->wrapped_file);
- sqlite3_free(chromium_file->wrapped_file_name);
- sqlite3_free(chromium_file->wrapped_file);
- memset(chromium_file, 0, sizeof(*chromium_file));
- return r;
-}
-
-int ChromiumRead(sqlite3_file* sqlite_file,
- void* p_buf,
- int i_amt,
- sqlite3_int64 i_ofst) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xRead(
- chromium_file->wrapped_file, p_buf, i_amt, i_ofst);
-}
-
-int ChromiumWrite(sqlite3_file* sqlite_file,
- const void* p_buf,
- int i_amt,
- sqlite3_int64 i_ofst) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xWrite(
- chromium_file->wrapped_file, p_buf, i_amt, i_ofst);
-}
-
-int ChromiumTruncate(sqlite3_file* sqlite_file, sqlite3_int64 size) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
-
- // The OSX and Linux sandboxes block ftruncate(), proxy to the browser
- // process.
- if (Platform::Current()->DatabaseSetFileSize(
- String::FromUTF8(chromium_file->wrapped_file_name), size))
- return SQLITE_OK;
- return SQLITE_IOERR_TRUNCATE;
-}
-
-int ChromiumSync(sqlite3_file* sqlite_file, int flags) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xSync(
- chromium_file->wrapped_file, flags);
-}
-
-int ChromiumFileSize(sqlite3_file* sqlite_file, sqlite3_int64* p_size) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xFileSize(
- chromium_file->wrapped_file, p_size);
-}
-
-int ChromiumLock(sqlite3_file* sqlite_file, int e_file_lock) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xLock(
- chromium_file->wrapped_file, e_file_lock);
-}
-
-int ChromiumUnlock(sqlite3_file* sqlite_file, int e_file_lock) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xUnlock(
- chromium_file->wrapped_file, e_file_lock);
-}
-
-int ChromiumCheckReservedLock(sqlite3_file* sqlite_file, int* p_res_out) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xCheckReservedLock(
- chromium_file->wrapped_file, p_res_out);
-}
-
-int ChromiumFileControl(sqlite3_file* sqlite_file, int op, void* p_arg) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xFileControl(
- chromium_file->wrapped_file, op, p_arg);
-}
-
-int ChromiumSectorSize(sqlite3_file* sqlite_file) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xSectorSize(
- chromium_file->wrapped_file);
-}
-
-int ChromiumDeviceCharacteristics(sqlite3_file* sqlite_file) {
- chromiumVfsFile* chromium_file =
- reinterpret_cast<chromiumVfsFile*>(sqlite_file);
- return chromium_file->wrapped_file->pMethods->xDeviceCharacteristics(
- chromium_file->wrapped_file);
-}
-
-// Opens a file.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// fileName - the name of the file.
-// id - the structure that will manipulate the newly opened file.
-// desiredFlags - the desired open mode flags.
-// usedFlags - the actual open mode flags that were used.
-int ChromiumOpenInternal(sqlite3_vfs* vfs,
- const char* file_name,
- sqlite3_file* id,
- int desired_flags,
- int* used_flags) {
- base::File file = Platform::Current()->DatabaseOpenFile(
- String::FromUTF8(file_name), desired_flags);
- if (!file.IsValid() && (desired_flags & SQLITE_OPEN_READWRITE)) {
- desired_flags =
- (desired_flags & ~(SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)) |
- SQLITE_OPEN_READONLY;
- file = Platform::Current()->DatabaseOpenFile(String::FromUTF8(file_name),
- desired_flags);
- }
- if (!file.IsValid())
- return SQLITE_CANTOPEN;
-
- if (used_flags)
- *used_flags = desired_flags;
-
- int fd = file.TakePlatformFile();
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
-
- // The mask 0x00007F00 gives us the 7 bits that determine the type of the file
- // SQLite is trying to open.
- int file_type = desired_flags & 0x00007F00;
- int no_lock = (file_type != SQLITE_OPEN_MAIN_DB);
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return chromium_sqlite3_fill_in_unix_sqlite3_file(
- wrapped_vfs, fd, id, file_name, no_lock, desired_flags);
-}
-
-int ChromiumOpen(sqlite3_vfs* vfs,
- const char* file_name,
- sqlite3_file* id,
- int desired_flags,
- int* used_flags) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- sqlite3_file* wrapped_file =
- static_cast<sqlite3_file*>(sqlite3_malloc(wrapped_vfs->szOsFile));
- if (!wrapped_file)
- return SQLITE_NOMEM;
-
- // Make a local copy of the file name. SQLite's os_unix.c appears to be
- // written to allow caching the pointer passed in to this function, but that
- // seems brittle.
- char* wrapped_file_name = sqlite3_mprintf("%s", file_name);
- if (!wrapped_file_name) {
- sqlite3_free(wrapped_file);
- return SQLITE_NOMEM;
- }
-
- // SQLite's unixOpen() makes assumptions about the structure of |fileName|.
- // Our local copy may not answer those assumptions correctly.
- int rc = ChromiumOpenInternal(vfs, file_name, wrapped_file, desired_flags,
- used_flags);
- if (rc != SQLITE_OK) {
- sqlite3_free(wrapped_file_name);
- sqlite3_free(wrapped_file);
- return rc;
- }
-
- static sqlite3_io_methods chromium_io_methods = {
- 1,
- ChromiumClose,
- ChromiumRead,
- ChromiumWrite,
- ChromiumTruncate,
- ChromiumSync,
- ChromiumFileSize,
- ChromiumLock,
- ChromiumUnlock,
- ChromiumCheckReservedLock,
- ChromiumFileControl,
- ChromiumSectorSize,
- ChromiumDeviceCharacteristics,
- // Methods above are valid for version 1.
- };
- chromiumVfsFile* chromium_file = reinterpret_cast<chromiumVfsFile*>(id);
- chromium_file->p_methods = &chromium_io_methods;
- chromium_file->wrapped_file = wrapped_file;
- chromium_file->wrapped_file_name = wrapped_file_name;
- return SQLITE_OK;
-}
-
-// Deletes the given file.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// fileName - the name of the file.
-// syncDir - determines if the directory to which this file belongs
-// should be synched after the file is deleted.
-int ChromiumDelete(sqlite3_vfs*, const char* file_name, int sync_dir) {
- return Platform::Current()->DatabaseDeleteFile(String::FromUTF8(file_name),
- sync_dir);
-}
-
-// Check the existence and status of the given file.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// fileName - the name of the file.
-// flag - the type of test to make on this file.
-// res - the result.
-int ChromiumAccess(sqlite3_vfs*, const char* file_name, int flag, int* res) {
- int attr = static_cast<int>(Platform::Current()->DatabaseGetFileAttributes(
- String::FromUTF8(file_name)));
- if (attr < 0) {
- *res = 0;
- return SQLITE_OK;
- }
-
- switch (flag) {
- case SQLITE_ACCESS_EXISTS:
- *res = 1; // if the file doesn't exist, attr < 0
- break;
- case SQLITE_ACCESS_READWRITE:
- *res = (attr & W_OK) && (attr & R_OK);
- break;
- case SQLITE_ACCESS_READ:
- *res = (attr & R_OK);
- break;
- default:
- return SQLITE_ERROR;
- }
-
- return SQLITE_OK;
-}
-
-// Turns a relative pathname into a full pathname.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// relativePath - the relative path.
-// bufSize - the size of the output buffer in bytes.
-// absolutePath - the output buffer where the absolute path will be stored.
-int ChromiumFullPathname(sqlite3_vfs* vfs,
- const char* relative_path,
- int buf_size,
- char* absolute_path) {
- // The renderer process doesn't need to know the absolute path of the file
- sqlite3_snprintf(buf_size, absolute_path, "%s", relative_path);
- return SQLITE_OK;
-}
-
-// Do not allow loading libraries in the renderer.
-void* ChromiumDlOpen(sqlite3_vfs*, const char*) {
- return nullptr;
-}
-
-void ChromiumDlError(sqlite3_vfs*, int buf_size, char* error_buffer) {
- sqlite3_snprintf(buf_size, error_buffer, "Dynamic loading not supported");
-}
-
-void (*ChromiumDlSym(sqlite3_vfs*, void*, const char*))(void) {
- return nullptr;
-}
-
-void ChromiumDlClose(sqlite3_vfs*, void*) {}
-
-int ChromiumRandomness(sqlite3_vfs* vfs, int buf_size, char* buffer) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return wrapped_vfs->xRandomness(wrapped_vfs, buf_size, buffer);
-}
-
-int ChromiumSleep(sqlite3_vfs* vfs, int microseconds) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return wrapped_vfs->xSleep(wrapped_vfs, microseconds);
-}
-
-int ChromiumGetLastError(sqlite3_vfs* vfs, int n_buf, char* z_buf) {
- if (n_buf && z_buf)
- *z_buf = '\0';
- return 0;
-}
-
-int ChromiumCurrentTimeInt64(sqlite3_vfs* vfs, sqlite3_int64* now) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return wrapped_vfs->xCurrentTimeInt64(wrapped_vfs, now);
-}
-
-} // namespace
-
-void SQLiteFileSystem::RegisterSQLiteVFS() {
- sqlite3_vfs* wrapped_vfs = sqlite3_vfs_find("unix");
-
- // These are implemented by delegating to |wrappedVfs|.
- // TODO(shess): Implement local versions.
- DCHECK(wrapped_vfs->xRandomness);
- DCHECK(wrapped_vfs->xSleep);
- DCHECK(wrapped_vfs->xCurrentTimeInt64);
-
- static sqlite3_vfs chromium_vfs = {2, // SQLite VFS API version.
- sizeof(chromiumVfsFile),
- wrapped_vfs->mxPathname,
- nullptr,
- "chromium_vfs",
- wrapped_vfs,
- ChromiumOpen,
- ChromiumDelete,
- ChromiumAccess,
- ChromiumFullPathname,
- ChromiumDlOpen,
- ChromiumDlError,
- ChromiumDlSym,
- ChromiumDlClose,
- ChromiumRandomness,
- ChromiumSleep,
- nullptr, // CurrentTime is deprecated.
- ChromiumGetLastError,
- ChromiumCurrentTimeInt64};
- sqlite3_vfs_register(&chromium_vfs, 0);
-}
-
-} // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc
deleted file mode 100644
index 093bb8c..0000000
--- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system_win.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_file_system.h"
-
-#include <windows.h>
-
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/sqlite/sqlite3.h"
-
-namespace blink {
-
-// Chromium's Windows implementation of SQLite VFS
-namespace {
-
-// Opens a file.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// fileName - the name of the file.
-// id - the structure that will manipulate the newly opened file.
-// desiredFlags - the desired open mode flags.
-// usedFlags - the actual open mode flags that were used.
-int ChromiumOpen(sqlite3_vfs*,
- const char* file_name,
- sqlite3_file* id,
- int desired_flags,
- int* used_flags) {
- base::File file = Platform::Current()->DatabaseOpenFile(
- String::FromUTF8(file_name), desired_flags);
- if (!file.IsValid() && (desired_flags & SQLITE_OPEN_READWRITE)) {
- desired_flags =
- (desired_flags & ~(SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)) |
- SQLITE_OPEN_READONLY;
- file = Platform::Current()->DatabaseOpenFile(String::FromUTF8(file_name),
- desired_flags);
- }
- if (!file.IsValid())
- return SQLITE_CANTOPEN;
-
- if (used_flags)
- *used_flags = desired_flags;
-
- HANDLE handle = file.TakePlatformFile();
- chromium_sqlite3_initialize_win_sqlite3_file(id, handle);
- return SQLITE_OK;
-}
-
-// Deletes the given file.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// fileName - the name of the file.
-// syncDir - determines if the directory to which this file belongs
-// should be synched after the file is deleted.
-int ChromiumDelete(sqlite3_vfs*, const char* file_name, int) {
- return Platform::Current()->DatabaseDeleteFile(String::FromUTF8(file_name),
- false);
-}
-
-// Check the existence and status of the given file.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// fileName - the name of the file.
-// flag - the type of test to make on this file.
-// res - the result.
-int ChromiumAccess(sqlite3_vfs*, const char* file_name, int flag, int* res) {
- DWORD attr = Platform::Current()->DatabaseGetFileAttributes(
- String::FromUTF8(file_name));
- switch (flag) {
- case SQLITE_ACCESS_READ:
- case SQLITE_ACCESS_EXISTS:
- *res = (attr != INVALID_FILE_ATTRIBUTES);
- break;
- case SQLITE_ACCESS_READWRITE:
- *res = ((attr & FILE_ATTRIBUTE_READONLY) == 0);
- break;
- default:
- return SQLITE_ERROR;
- }
-
- return SQLITE_OK;
-}
-
-// Turns a relative pathname into a full pathname.
-//
-// vfs - pointer to the sqlite3_vfs object.
-// relativePath - the relative path.
-// bufSize - the size of the output buffer in bytes.
-// absolutePath - the output buffer where the absolute path will be stored.
-int ChromiumFullPathname(sqlite3_vfs* vfs,
- const char* relative_path,
- int buf_size,
- char* absolute_path) {
- // The renderer process doesn't need to know the absolute path of the file
- sqlite3_snprintf(buf_size, absolute_path, "%s", relative_path);
- return SQLITE_OK;
-}
-
-// Do not allow loading libraries in the renderer.
-void* ChromiumDlOpen(sqlite3_vfs*, const char*) {
- return 0;
-}
-
-void ChromiumDlError(sqlite3_vfs*, int buf_size, char* error_buffer) {
- sqlite3_snprintf(buf_size, error_buffer, "Dynamic loading not supported");
-}
-
-void (*ChromiumDlSym(sqlite3_vfs*, void*, const char*))(void) {
- return 0;
-}
-
-void ChromiumDlClose(sqlite3_vfs*, void*) {}
-
-int ChromiumRandomness(sqlite3_vfs* vfs, int buf_size, char* buffer) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return wrapped_vfs->xRandomness(wrapped_vfs, buf_size, buffer);
-}
-
-int ChromiumSleep(sqlite3_vfs* vfs, int microseconds) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return wrapped_vfs->xSleep(wrapped_vfs, microseconds);
-}
-
-int ChromiumGetLastError(sqlite3_vfs* vfs, int n_buf, char* z_buf) {
- if (n_buf && z_buf)
- *z_buf = '\0';
- return 0;
-}
-
-int ChromiumCurrentTimeInt64(sqlite3_vfs* vfs, sqlite3_int64* now) {
- sqlite3_vfs* wrapped_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
- return wrapped_vfs->xCurrentTimeInt64(wrapped_vfs, now);
-}
-
-} // namespace
-
-void SQLiteFileSystem::RegisterSQLiteVFS() {
- sqlite3_vfs* wrapped_vfs = sqlite3_vfs_find("win32");
-
- // These are implemented by delegating to |wrappedVfs|.
- // TODO(shess): Implement local versions.
- DCHECK(wrapped_vfs->xRandomness);
- DCHECK(wrapped_vfs->xSleep);
- DCHECK(wrapped_vfs->xCurrentTimeInt64);
-
- static sqlite3_vfs chromium_vfs = {2, // SQLite VFS API version.
- wrapped_vfs->szOsFile,
- wrapped_vfs->mxPathname,
- 0,
- "chromium_vfs",
- wrapped_vfs,
- ChromiumOpen,
- ChromiumDelete,
- ChromiumAccess,
- ChromiumFullPathname,
- ChromiumDlOpen,
- ChromiumDlError,
- ChromiumDlSym,
- ChromiumDlClose,
- ChromiumRandomness,
- ChromiumSleep,
- nullptr, // CurrentTime is deprecated.
- ChromiumGetLastError,
- ChromiumCurrentTimeInt64};
- sqlite3_vfs_register(&chromium_vfs, 0);
-}
-
-} // namespace blink
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index fd87285f0..7030038 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -40,6 +40,7 @@
'base::MakeRefCounted',
'base::Optional',
'base::OptionalOrNullptr',
+ 'base::PlatformThread',
'base::PlatformThreadId',
'base::RefCountedData',
'base::RunLoop',
diff --git a/third_party/blink/web_tests/storage/websql/fts-pointer-leak-742407.html b/third_party/blink/web_tests/storage/websql/fts-pointer-leak-742407.html
index 95add45..dc722e3 100644
--- a/third_party/blink/web_tests/storage/websql/fts-pointer-leak-742407.html
+++ b/third_party/blink/web_tests/storage/websql/fts-pointer-leak-742407.html
@@ -8,7 +8,8 @@
async_test(testCase => {
const database = openDatabase(
- 'Fts3CrashTest', '1.0', 'Database for FTS3 crash test', 1024 * 1024);
+ 'Fts3PointerLeakTest', '1.0', 'Database for FTS3 pointer leak test',
+ 1024 * 1024);
assert_not_equals(database, null, 'openDatabase should not fail');
database.transaction(testCase.step_func(transaction => {