From ead3a2abbfc347b0f562c1e051b370a0617ee8aa Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 20 May 2023 15:43:44 +0300 Subject: Fix loading SQLite extensions * src/sqlite.c (sqlite3_db_config) [WINDOWSNT]: Load from the DLL. (Fsqlite_load_extension): Use 'sqlite3_db_config' to enable and disable loading of extensions. Add a few free extensions to the allow-list. Fix testing for the ".dll" extension. (Bug#63590) * test/src/sqlite-tests.el (sqlite-load-extension): Fix the test to require successful load if the extension does exist. --- src/sqlite.c | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) (limited to 'src/sqlite.c') diff --git a/src/sqlite.c b/src/sqlite.c index 0361514766a..77ce61ba657 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -23,6 +23,8 @@ YOSHIDA , which can be found at: https://github.com/syohex/emacs-sqlite3 */ #include + +#include #include "lisp.h" #include "coding.h" @@ -80,6 +82,9 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, (sqlite3*, const char*, const char*, char**)); # undef sqlite3_load_extension # define sqlite3_load_extension fn_sqlite3_load_extension +DEF_DLL_FN (SQLITE_API int, sqlite3_db_config, (sqlite3*, int, ...)); +# undef sqlite3_db_config +# define sqlite3_db_config fn_sqlite3_db_config # endif # undef sqlite3_finalize @@ -172,6 +177,7 @@ load_dll_functions (HMODULE library) LOAD_DLL_FN (library, sqlite3_exec); # ifdef HAVE_SQLITE3_LOAD_EXTENSION LOAD_DLL_FN (library, sqlite3_load_extension); + LOAD_DLL_FN (library, sqlite3_db_config); # endif LOAD_DLL_FN (library, sqlite3_prepare_v2); return true; @@ -684,9 +690,28 @@ Only modules on Emacs' list of allowed modules can be loaded. */) CHECK_STRING (module); /* Add names of useful and free modules here. */ - const char *allowlist[3] = { "pcre", "csvtable", NULL }; + const char *allowlist[] = { + "base64", + "cksumvfs", + "compress", + "csv", + "csvtable", + "fts3", + "icu", + "pcre", + "percentile", + "regexp", + "rot13", + "rtree", + "sha1", + "uuid", + "vfslog", + "zipfile", + NULL + }; char *name = SSDATA (Ffile_name_nondirectory (module)); - /* Possibly skip past a common prefix. */ + /* Possibly skip past a common prefix (libsqlite3_mod_ is used by + Debian, see https://packages.debian.org/source/sid/sqliteodbc). */ const char *prefix = "libsqlite3_mod_"; if (!strncmp (name, prefix, strlen (prefix))) name += strlen (prefix); @@ -697,7 +722,7 @@ Only modules on Emacs' list of allowed modules can be loaded. */) if (strlen (*allow) < strlen (name) && !strncmp (*allow, name, strlen (*allow)) && (!strcmp (name + strlen (*allow), ".so") - || !strcmp (name + strlen (*allow), ".DLL"))) + || !strcasecmp (name + strlen (*allow), ".dll"))) { do_allow = true; break; @@ -707,12 +732,22 @@ Only modules on Emacs' list of allowed modules can be loaded. */) if (!do_allow) xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist")); - int result = sqlite3_load_extension - (XSQLITE (db)->db, - SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))), - NULL, NULL); - if (result == SQLITE_OK) - return Qt; + /* Expand all Lisp data explicitly, so as to avoid signaling an + error while extension loading is enabled -- we don't want to + "leak" this outside this function. */ + sqlite3 *sdb = XSQLITE (db)->db; + char *ext_fn = SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))); + /* Temporarily enable loading extensions via the C API. */ + int result = sqlite3_db_config (sdb, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, + NULL); + if (result == SQLITE_OK) + { + result = sqlite3_load_extension (sdb, ext_fn, NULL, NULL); + /* Disable loading extensions via C API. */ + sqlite3_db_config (sdb, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 0, NULL); + if (result == SQLITE_OK) + return Qt; + } return Qnil; } #endif /* HAVE_SQLITE3_LOAD_EXTENSION */ -- cgit v1.2.1 From a347b26cba2124496b1fa5adb75f43c8a05842a6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 14:30:31 +0300 Subject: Disable loading SQLite3 extensions when SQLite3 version is too old * src/sqlite.c (HAVE_LOAD_EXTENSION): Define to 1 only if enabling/disabling extension loading is supported as well. (load_dll_functions, Fsqlite_load_extension): Condition on HAVE_LOAD_EXTENSION, not on HAVE_SQLITE3_LOAD_EXTENSION. (Bug#63653) --- src/sqlite.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/sqlite.c') diff --git a/src/sqlite.c b/src/sqlite.c index 77ce61ba657..852e3746ef4 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -32,6 +32,17 @@ YOSHIDA , which can be found at: #include +/* Support for loading SQLite extensions requires the ability to + enable and disable loading of extensions (by default this is + disabled, and we want to keep it that way). The required macro is + available since SQLite 3.13. */ +# if defined HAVE_SQLITE3_LOAD_EXTENSION && \ + defined SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION +# define HAVE_LOAD_EXTENSION 1 +# else +# define HAVE_LOAD_EXTENSION 0 +# endif + #ifdef WINDOWSNT # include @@ -77,7 +88,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_exec, DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2, (sqlite3*, const char*, int, sqlite3_stmt**, const char**)); -# ifdef HAVE_SQLITE3_LOAD_EXTENSION +# if HAVE_LOAD_EXTENSION DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, (sqlite3*, const char*, const char*, char**)); # undef sqlite3_load_extension @@ -175,7 +186,7 @@ load_dll_functions (HMODULE library) LOAD_DLL_FN (library, sqlite3_column_text); LOAD_DLL_FN (library, sqlite3_column_name); LOAD_DLL_FN (library, sqlite3_exec); -# ifdef HAVE_SQLITE3_LOAD_EXTENSION +# if HAVE_LOAD_EXTENSION LOAD_DLL_FN (library, sqlite3_load_extension); LOAD_DLL_FN (library, sqlite3_db_config); # endif @@ -675,7 +686,7 @@ DEFUN ("sqlite-pragma", Fsqlite_pragma, Ssqlite_pragma, 2, 2, 0, SSDATA (concat2 (build_string ("PRAGMA "), pragma))); } -#ifdef HAVE_SQLITE3_LOAD_EXTENSION +#if HAVE_LOAD_EXTENSION DEFUN ("sqlite-load-extension", Fsqlite_load_extension, Ssqlite_load_extension, 2, 2, 0, doc: /* Load an SQlite MODULE into DB. @@ -750,7 +761,7 @@ Only modules on Emacs' list of allowed modules can be loaded. */) } return Qnil; } -#endif /* HAVE_SQLITE3_LOAD_EXTENSION */ +#endif /* HAVE_LOAD_EXTENSION */ DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0, doc: /* Return the next result set from SET. @@ -860,7 +871,7 @@ syms_of_sqlite (void) defsubr (&Ssqlite_commit); defsubr (&Ssqlite_rollback); defsubr (&Ssqlite_pragma); -#ifdef HAVE_SQLITE3_LOAD_EXTENSION +#if HAVE_LOAD_EXTENSION defsubr (&Ssqlite_load_extension); #endif defsubr (&Ssqlite_next); -- cgit v1.2.1 From 765edc204d45c0eb6d31e92c661355c1bd7315a9 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 17:53:07 +0300 Subject: ; Support SQLite3 extensions on macOS * src/sqlite.c (Fsqlite_load_extension): Support *.dylib extensions. (Bug#63653) --- src/sqlite.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/sqlite.c') diff --git a/src/sqlite.c b/src/sqlite.c index 852e3746ef4..fd528f2b0d5 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -730,10 +730,12 @@ Only modules on Emacs' list of allowed modules can be loaded. */) bool do_allow = false; for (const char **allow = allowlist; *allow; allow++) { - if (strlen (*allow) < strlen (name) - && !strncmp (*allow, name, strlen (*allow)) - && (!strcmp (name + strlen (*allow), ".so") - || !strcasecmp (name + strlen (*allow), ".dll"))) + ptrdiff_t allow_len = strlen (*allow); + if (allow_len < strlen (name) + && !strncmp (*allow, name, allow_len) + && (!strcmp (name + allow_len, ".so") + ||!strcmp (name + allow_len, ".dylib") + || !strcasecmp (name + allow_len, ".dll"))) { do_allow = true; break; -- cgit v1.2.1