emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 ead3a2abbfc: Fix loading SQLite extensions


From: Eli Zaretskii
Subject: emacs-29 ead3a2abbfc: Fix loading SQLite extensions
Date: Sat, 20 May 2023 08:44:08 -0400 (EDT)

branch: emacs-29
commit ead3a2abbfc347b0f562c1e051b370a0617ee8aa
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    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 ++++++++++++++++++++++++++++++++++++++++--------
 test/src/sqlite-tests.el | 23 +++++++++++++--------
 2 files changed, 58 insertions(+), 18 deletions(-)

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 <syohex@gmail.com>, which can be found at:
    https://github.com/syohex/emacs-sqlite3  */
 
 #include <config.h>
+
+#include <c-strcase.h>
 #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 */
diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el
index 460651def78..f7144c15887 100644
--- a/test/src/sqlite-tests.el
+++ b/test/src/sqlite-tests.el
@@ -197,10 +197,13 @@
      (sqlite-load-extension db "/usr/lib/sqlite3/"))
     (should-error
      (sqlite-load-extension db "/usr/lib/sqlite3"))
-    (should
-     (memq
-      (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so")
-      '(nil t)))
+    (if (eq system-type 'windows-nt)
+        (should
+         (eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.dll")
+             (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
      (sqlite-load-extension
@@ -211,11 +214,13 @@
     (should-error
      (sqlite-load-extension
       db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable"))
-    (should
-     (memq
-      (sqlite-load-extension
-       db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")
-      '(nil t)))))
+    (if (eq system-type 'windows-nt)
+        (should
+         (eq (sqlite-load-extension db "/usr/lib/sqlite3/csvtable.dll")
+             (file-readable-p "/usr/lib/sqlite3/csvtable.dll")))
+      (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 ()
   (skip-unless (sqlite-available-p))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]