From 5c2f599712c777d123d198266b05ca2c4cc8eba3 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Tue, 3 Dec 2024 15:15:46 -0800 Subject: [PATCH] sqlite: support `db.loadExtension` PR-URL: https://github.com/nodejs/node/pull/53900 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- Makefile | 3 + doc/api/errors.md | 10 ++ doc/api/permissions.md | 2 + doc/api/sqlite.md | 29 +++++ node.gyp | 20 ++++ src/node_errors.h | 2 + src/node_sqlite.cc | 111 +++++++++++++++++- src/node_sqlite.h | 8 +- .../test-permission-sqlite-load-extension.js | 18 +++ test/sqlite/extension.c | 94 +++++++++++++++ test/sqlite/test-sqlite-extensions.mjs | 108 +++++++++++++++++ test/sqlite/testcfg.py | 6 + tools/test.py | 1 + 13 files changed, 409 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-permission-sqlite-load-extension.js create mode 100644 test/sqlite/extension.c create mode 100644 test/sqlite/test-sqlite-extensions.mjs create mode 100644 test/sqlite/testcfg.py diff --git a/Makefile b/Makefile index c16998280f91b1..452ea0ddfc2c7f 100644 --- a/Makefile +++ b/Makefile @@ -294,6 +294,7 @@ coverage-report-js: ## Report JavaScript coverage results. cctest: all ## Run the C++ tests using the built `cctest` executable. @out/$(BUILDTYPE)/$@ --gtest_filter=$(GTEST_FILTER) $(NODE) ./test/embedding/test-embedding.js + $(NODE) ./test/sqlite/test-sqlite-extensions.mjs .PHONY: list-gtests list-gtests: ## List all available C++ gtests. @@ -574,6 +575,7 @@ test-ci: | clear-stalled bench-addons-build build-addons build-js-native-api-tes --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_JS_SUITES) $(CI_NATIVE_SUITES) $(CI_DOC) $(NODE) ./test/embedding/test-embedding.js + $(NODE) ./test/sqlite/test-sqlite-extensions.mjs $(info Clean up any leftover processes, error if found.) ps awwx | grep Release/node | grep -v grep | cat @PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \ @@ -1432,6 +1434,7 @@ LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \ test/cctest/*.h \ test/embedding/*.cc \ test/embedding/*.h \ + test/sqlite/*.c \ test/fixtures/*.c \ test/js-native-api/*/*.cc \ test/node-api/*/*.cc \ diff --git a/doc/api/errors.md b/doc/api/errors.md index 659af3bc8207fa..be0d27995778b4 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -2174,6 +2174,16 @@ added: An ESM loader hook returned without calling `next()` and without explicitly signaling a short circuit. + + +### `ERR_LOAD_SQLITE_EXTENSION` + + + +An error occurred while loading a SQLite extension. + ### `ERR_MEMORY_ALLOCATION_FAILED` diff --git a/doc/api/permissions.md b/doc/api/permissions.md index a03285e28641e8..d03913e7858d66 100644 --- a/doc/api/permissions.md +++ b/doc/api/permissions.md @@ -147,6 +147,8 @@ There are constraints you need to know before using this system: flags that can be set via runtime through `v8.setFlagsFromString`. * OpenSSL engines cannot be requested at runtime when the Permission Model is enabled, affecting the built-in crypto, https, and tls modules. +* Run-Time Loadable Extensions cannot be loaded when the Permission Model is + enabled, affecting the sqlite module. * Using existing file descriptors via the `node:fs` module bypasses the Permission Model. diff --git a/doc/api/sqlite.md b/doc/api/sqlite.md index 9279ef973807f9..33d7f516035d95 100644 --- a/doc/api/sqlite.md +++ b/doc/api/sqlite.md @@ -108,6 +108,10 @@ added: v22.5.0 [double-quoted string literals][]. This is not recommended but can be enabled for compatibility with legacy database schemas. **Default:** `false`. + * `allowExtension` {boolean} If `true`, the `loadExtension` SQL function + and the `loadExtension()` method are enabled. + You can call `enableLoadExtension(false)` later to disable this feature. + **Default:** `false`. Constructs a new `DatabaseSync` instance. @@ -120,6 +124,30 @@ added: v22.5.0 Closes the database connection. An exception is thrown if the database is not open. This method is a wrapper around [`sqlite3_close_v2()`][]. +### `database.loadExtension(path)` + + + +* `path` {string} The path to the shared library to load. + +Loads a shared library into the database connection. This method is a wrapper +around [`sqlite3_load_extension()`][]. It is required to enable the +`allowExtension` option when constructing the `DatabaseSync` instance. + +### `database.enableLoadExtension(allow)` + + + +* `allow` {boolean} Whether to allow loading extensions. + +Enables or disables the `loadExtension` SQL function, and the `loadExtension()` +method. When `allowExtension` is `false` when constructing, you cannot enable +loading extensions for security reasons. + ### `database.exec(sql)`