ncruces / go-sqlite3

Go bindings to SQLite using wazero
https://pkg.go.dev/github.com/ncruces/go-sqlite3
MIT License
402 stars 12 forks source link

Usage of memdb VFS #129

Closed beldmian closed 1 month ago

beldmian commented 1 month ago

While testing memdb VFS found some strange behaviour - for code:

package main

import (
  "database/sql"

  _ "github.com/ncruces/go-sqlite3/driver"
  _ "github.com/ncruces/go-sqlite3/embed"
  _ "github.com/ncruces/go-sqlite3/vfs/memdb"
  "github.com/ncruces/go-sqlite3/vfs"
)

func main() {
  db, err := sql.Open("sqlite3", "file:/vuln.db?vfs=memdb")
  if err != nil {
    panic(err)
  }
  if _, err := db.Exec("CREATE TABLE user(id INTEGER PRIMARY KEY);"); err != nil {
    panic(err)
  }
  fs := vfs.Find("memdb")
  if err := db.Close(); err != nil {
    panic(err)
  }
  file, _, err := fs.Open("/vuln.db", vfs.OPEN_READONLY)
  if err != nil {
    panic(err)
  }
  if err := file.Close(); err != nil {
    panic(err)
  }
}

There is an error with fs.Open(...):

panic: sqlite3: unable to open database file                                                                                                                                        

goroutine 1 [running]:                                                                                                                                                              
main.main()                                                                                                                                                                         
        /Users/a1/docs/prog/work/test/main.go:26 +0x107                                                                                                                             
exit status 2 

Am I doing something wrong?

ncruces commented 1 month ago

The first question is: why would you want to do this? What actual problem are you're trying to solve by opening the file directly with the VFS?

VFSes are really meant to be called by SQLite, not by yourself. There's no harm in doing it, but if you are going to do it, you're going to need to understand what promises SQLite makes when it calls a VFS.

A little debugging would tell you need to pass more flags to Open, because that's what SQLite does. That won't fix anything though, because by the time you call Open the file has been deleted.

So, what problem are you trying to solve?

ncruces commented 1 month ago

As for why the database is deleted by then, shared memdb files are reference counted. When you close the last connection to one, it gets deleted.

If you want to work around that, you can explicitly call memdb.Create.