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.
This commit is contained in:
parent
a6bddd1765
commit
ead3a2abbf
2 changed files with 58 additions and 18 deletions
53
src/sqlite.c
53
src/sqlite.c
|
@ -23,6 +23,8 @@ YOSHIDA <syohex@gmail.com>, which can be found at:
|
||||||
https://github.com/syohex/emacs-sqlite3 */
|
https://github.com/syohex/emacs-sqlite3 */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <c-strcase.h>
|
||||||
#include "lisp.h"
|
#include "lisp.h"
|
||||||
#include "coding.h"
|
#include "coding.h"
|
||||||
|
|
||||||
|
@ -80,6 +82,9 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
|
||||||
(sqlite3*, const char*, const char*, char**));
|
(sqlite3*, const char*, const char*, char**));
|
||||||
# undef sqlite3_load_extension
|
# undef sqlite3_load_extension
|
||||||
# define sqlite3_load_extension fn_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
|
# endif
|
||||||
|
|
||||||
# undef sqlite3_finalize
|
# undef sqlite3_finalize
|
||||||
|
@ -172,6 +177,7 @@ load_dll_functions (HMODULE library)
|
||||||
LOAD_DLL_FN (library, sqlite3_exec);
|
LOAD_DLL_FN (library, sqlite3_exec);
|
||||||
# ifdef HAVE_SQLITE3_LOAD_EXTENSION
|
# ifdef HAVE_SQLITE3_LOAD_EXTENSION
|
||||||
LOAD_DLL_FN (library, sqlite3_load_extension);
|
LOAD_DLL_FN (library, sqlite3_load_extension);
|
||||||
|
LOAD_DLL_FN (library, sqlite3_db_config);
|
||||||
# endif
|
# endif
|
||||||
LOAD_DLL_FN (library, sqlite3_prepare_v2);
|
LOAD_DLL_FN (library, sqlite3_prepare_v2);
|
||||||
return true;
|
return true;
|
||||||
|
@ -684,9 +690,28 @@ Only modules on Emacs' list of allowed modules can be loaded. */)
|
||||||
CHECK_STRING (module);
|
CHECK_STRING (module);
|
||||||
|
|
||||||
/* Add names of useful and free modules here. */
|
/* 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));
|
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_";
|
const char *prefix = "libsqlite3_mod_";
|
||||||
if (!strncmp (name, prefix, strlen (prefix)))
|
if (!strncmp (name, prefix, strlen (prefix)))
|
||||||
name += 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)
|
if (strlen (*allow) < strlen (name)
|
||||||
&& !strncmp (*allow, name, strlen (*allow))
|
&& !strncmp (*allow, name, strlen (*allow))
|
||||||
&& (!strcmp (name + strlen (*allow), ".so")
|
&& (!strcmp (name + strlen (*allow), ".so")
|
||||||
|| !strcmp (name + strlen (*allow), ".DLL")))
|
|| !strcasecmp (name + strlen (*allow), ".dll")))
|
||||||
{
|
{
|
||||||
do_allow = true;
|
do_allow = true;
|
||||||
break;
|
break;
|
||||||
|
@ -707,12 +732,22 @@ Only modules on Emacs' list of allowed modules can be loaded. */)
|
||||||
if (!do_allow)
|
if (!do_allow)
|
||||||
xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist"));
|
xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist"));
|
||||||
|
|
||||||
int result = sqlite3_load_extension
|
/* Expand all Lisp data explicitly, so as to avoid signaling an
|
||||||
(XSQLITE (db)->db,
|
error while extension loading is enabled -- we don't want to
|
||||||
SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))),
|
"leak" this outside this function. */
|
||||||
NULL, NULL);
|
sqlite3 *sdb = XSQLITE (db)->db;
|
||||||
if (result == SQLITE_OK)
|
char *ext_fn = SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil)));
|
||||||
return Qt;
|
/* 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;
|
return Qnil;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SQLITE3_LOAD_EXTENSION */
|
#endif /* HAVE_SQLITE3_LOAD_EXTENSION */
|
||||||
|
|
|
@ -197,10 +197,13 @@
|
||||||
(sqlite-load-extension db "/usr/lib/sqlite3/"))
|
(sqlite-load-extension db "/usr/lib/sqlite3/"))
|
||||||
(should-error
|
(should-error
|
||||||
(sqlite-load-extension db "/usr/lib/sqlite3"))
|
(sqlite-load-extension db "/usr/lib/sqlite3"))
|
||||||
(should
|
(if (eq system-type 'windows-nt)
|
||||||
(memq
|
(should
|
||||||
(sqlite-load-extension db "/usr/lib/sqlite3/pcre.so")
|
(eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.dll")
|
||||||
'(nil t)))
|
(file-readable-p "/usr/lib/sqlite3/pcre.dll")))
|
||||||
|
(should
|
||||||
|
(eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so")
|
||||||
|
(file-readable-p "/usr/lib/sqlite3/pcre.so"))))
|
||||||
|
|
||||||
(should-error
|
(should-error
|
||||||
(sqlite-load-extension
|
(sqlite-load-extension
|
||||||
|
@ -211,11 +214,13 @@
|
||||||
(should-error
|
(should-error
|
||||||
(sqlite-load-extension
|
(sqlite-load-extension
|
||||||
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable"))
|
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable"))
|
||||||
(should
|
(if (eq system-type 'windows-nt)
|
||||||
(memq
|
(should
|
||||||
(sqlite-load-extension
|
(eq (sqlite-load-extension db "/usr/lib/sqlite3/csvtable.dll")
|
||||||
db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")
|
(file-readable-p "/usr/lib/sqlite3/csvtable.dll")))
|
||||||
'(nil t)))))
|
(should
|
||||||
|
(eq (sqlite-load-extension db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")
|
||||||
|
(file-readable-p "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so"))))))
|
||||||
|
|
||||||
(ert-deftest sqlite-blob ()
|
(ert-deftest sqlite-blob ()
|
||||||
(skip-unless (sqlite-available-p))
|
(skip-unless (sqlite-available-p))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue