From e2b915c98c950cc6bfd7bc48e06070859aed9a38 Mon Sep 17 00:00:00 2001 From: Dan Peterson Date: Mon, 5 Apr 2021 20:27:46 -0300 Subject: [PATCH] driver: set libc environment in init modernc.org/libc.Start does this when wrapping funcs main to seed data for libc.Xgetenv and friends. However, sqlite doesn't use libc.Start. It sets libc bits up in an init func. This leaves the libc view of the enivorment empty/null. When the sqlite "localtime" modifier used with datetime/strftime/etc, sqlite eventually calls libc.Xlocaltime which wants to read TZ from the environment. With an empty/null libc enivornment, this segfaults. To fix that, call libc.SetEnviron in func init like libc.Start does. Fixes https://gitlab.com/cznic/sqlite/-/issues/49 --- all_test.go | 13 +++++++++++++ sqlite.go | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/all_test.go b/all_test.go index fd8d4a2..b69a162 100644 --- a/all_test.go +++ b/all_test.go @@ -1178,6 +1178,19 @@ func TestTimeScan(t *testing.T) { } } +// https://gitlab.com/cznic/sqlite/-/issues/49 +func TestTimeLocaltime(t *testing.T) { + db, err := sql.Open(driverName, "file::memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + if _, err := db.Exec("select datetime('now', 'localtime')"); err != nil { + t.Fatal(err) + } +} + // https://sqlite.org/lang_expr.html#varparam // https://gitlab.com/cznic/sqlite/-/issues/42 func TestBinding(t *testing.T) { diff --git a/sqlite.go b/sqlite.go index 269349f..1eca234 100644 --- a/sqlite.go +++ b/sqlite.go @@ -14,6 +14,7 @@ import ( "fmt" "io" "math" + "os" "reflect" "runtime" "strconv" @@ -119,6 +120,9 @@ var ( func init() { tls := libc.NewTLS() + + libc.SetEnviron(tls, os.Environ()) + if sqlite3.Xsqlite3_threadsafe(tls) == 0 { panic(fmt.Errorf("sqlite: thread safety configuration error")) }