Skip to content

Commit 98a44bc

Browse files
rittnejeJesse Rittner
and
Jesse Rittner
authored
report actual error message if sqlite3_load_extension fails (#800)
* report actual error message if sqlite3_load_extension fails * more fixes and test cases Co-authored-by: Jesse Rittner <[email protected]>
1 parent 58b2310 commit 98a44bc

File tree

5 files changed

+112
-25
lines changed

5 files changed

+112
-25
lines changed

_example/mod_regexp/Makefile

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
ifeq ($(OS),Windows_NT)
22
EXE=extension.exe
3-
EXT=sqlite3_mod_regexp.dll
3+
LIB_EXT=dll
44
RM=cmd /c del
55
LDFLAG=
66
else
77
EXE=extension
8-
EXT=sqlite3_mod_regexp.so
9-
RM=rm
8+
ifeq ($(shell uname -s),Darwin)
9+
LIB_EXT=dylib
10+
else
11+
LIB_EXT=so
12+
endif
13+
RM=rm -f
1014
LDFLAG=-fPIC
1115
endif
16+
LIB=sqlite3_mod_regexp.$(LIB_EXT)
1217

13-
all : $(EXE) $(EXT)
18+
all : $(EXE) $(LIB)
1419

1520
$(EXE) : extension.go
1621
go build $<
1722

18-
$(EXT) : sqlite3_mod_regexp.c
23+
$(LIB) : sqlite3_mod_regexp.c
1924
gcc $(LDFLAG) -shared -o $@ $< -lsqlite3 -lpcre
2025

2126
clean :
22-
@-$(RM) $(EXE) $(EXT)
27+
@-$(RM) $(EXE) $(LIB)

_example/mod_vtable/Makefile

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
ifeq ($(OS),Windows_NT)
22
EXE=extension.exe
3-
EXT=sqlite3_mod_vtable.dll
3+
LIB_EXT=dll
44
RM=cmd /c del
55
LIBCURL=-lcurldll
66
LDFLAG=
77
else
88
EXE=extension
9-
EXT=sqlite3_mod_vtable.so
10-
RM=rm
9+
ifeq ($(shell uname -s),Darwin)
10+
LIB_EXT=dylib
11+
else
12+
LIB_EXT=so
13+
endif
14+
RM=rm -f
1115
LDFLAG=-fPIC
1216
LIBCURL=-lcurl
1317
endif
18+
LIB=sqlite3_mod_vtable.$(LIB_EXT)
1419

15-
all : $(EXE) $(EXT)
20+
all : $(EXE) $(LIB)
1621

1722
$(EXE) : extension.go
1823
go build $<
1924

20-
$(EXT) : sqlite3_mod_vtable.cc
25+
$(LIB) : sqlite3_mod_vtable.cc
2126
g++ $(LDFLAG) -shared -o $@ $< -lsqlite3 $(LIBCURL)
2227

2328
clean :
24-
@-$(RM) $(EXE) $(EXT)
29+
@-$(RM) $(EXE) $(LIB)

_example/mod_vtable/sqlite3_mod_vtable.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <string>
22
#include <sstream>
3-
#include <sqlite3-binding.h>
3+
#include <sqlite3.h>
44
#include <sqlite3ext.h>
55
#include <curl/curl.h>
66
#include "picojson.h"

sqlite3_load_extension.go

+26-12
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,17 @@ func (c *SQLiteConn) loadExtensions(extensions []string) error {
2828
}
2929

3030
for _, extension := range extensions {
31-
cext := C.CString(extension)
32-
defer C.free(unsafe.Pointer(cext))
33-
rv = C.sqlite3_load_extension(c.db, cext, nil, nil)
34-
if rv != C.SQLITE_OK {
31+
if err := c.loadExtension(extension, nil); err != nil {
3532
C.sqlite3_enable_load_extension(c.db, 0)
36-
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
33+
return err
3734
}
3835
}
3936

4037
rv = C.sqlite3_enable_load_extension(c.db, 0)
4138
if rv != C.SQLITE_OK {
4239
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
4340
}
41+
4442
return nil
4543
}
4644

@@ -51,19 +49,35 @@ func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
5149
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
5250
}
5351

54-
clib := C.CString(lib)
55-
defer C.free(unsafe.Pointer(clib))
56-
centry := C.CString(entry)
57-
defer C.free(unsafe.Pointer(centry))
52+
if err := c.loadExtension(lib, &entry); err != nil {
53+
C.sqlite3_enable_load_extension(c.db, 0)
54+
return err
55+
}
5856

59-
rv = C.sqlite3_load_extension(c.db, clib, centry, nil)
57+
rv = C.sqlite3_enable_load_extension(c.db, 0)
6058
if rv != C.SQLITE_OK {
6159
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
6260
}
6361

64-
rv = C.sqlite3_enable_load_extension(c.db, 0)
62+
return nil
63+
}
64+
65+
func (c *SQLiteConn) loadExtension(lib string, entry *string) error {
66+
clib := C.CString(lib)
67+
defer C.free(unsafe.Pointer(clib))
68+
69+
var centry *C.char
70+
if entry != nil {
71+
centry := C.CString(*entry)
72+
defer C.free(unsafe.Pointer(centry))
73+
}
74+
75+
var errMsg *C.char
76+
defer C.sqlite3_free(unsafe.Pointer(errMsg))
77+
78+
rv := C.sqlite3_load_extension(c.db, clib, centry, &errMsg)
6579
if rv != C.SQLITE_OK {
66-
return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
80+
return errors.New(C.GoString(errMsg))
6781
}
6882

6983
return nil

sqlite3_load_extension_test.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (C) 2019 Yasuhiro Matsumoto <[email protected]>.
2+
//
3+
// Use of this source code is governed by an MIT-style
4+
// license that can be found in the LICENSE file.
5+
6+
// +build !sqlite_omit_load_extension
7+
8+
package sqlite3
9+
10+
import (
11+
"database/sql"
12+
"testing"
13+
)
14+
15+
func TestExtensionsError(t *testing.T) {
16+
sql.Register("sqlite3_TestExtensionsError",
17+
&SQLiteDriver{
18+
Extensions: []string{
19+
"foobar",
20+
},
21+
},
22+
)
23+
24+
db, err := sql.Open("sqlite3_TestExtensionsError", ":memory:")
25+
if err != nil {
26+
t.Fatal(err)
27+
}
28+
defer db.Close()
29+
30+
err = db.Ping()
31+
if err == nil {
32+
t.Fatal("expected error loading non-existent extension")
33+
}
34+
35+
if err.Error() == "not an error" {
36+
t.Fatal("expected error from sqlite3_enable_load_extension to be returned")
37+
}
38+
}
39+
40+
func TestLoadExtensionError(t *testing.T) {
41+
sql.Register("sqlite3_TestLoadExtensionError",
42+
&SQLiteDriver{
43+
ConnectHook: func(c *SQLiteConn) error {
44+
return c.LoadExtension("foobar", "")
45+
},
46+
},
47+
)
48+
49+
db, err := sql.Open("sqlite3_TestLoadExtensionError", ":memory:")
50+
if err != nil {
51+
t.Fatal(err)
52+
}
53+
defer db.Close()
54+
55+
err = db.Ping()
56+
if err == nil {
57+
t.Fatal("expected error loading non-existent extension")
58+
}
59+
60+
if err.Error() == "not an error" {
61+
t.Fatal("expected error from sqlite3_enable_load_extension to be returned")
62+
}
63+
}

0 commit comments

Comments
 (0)