Improved error handling.

This commit is contained in:
Nuno Cruces
2023-01-19 14:31:32 +00:00
parent 2cfd5de40e
commit 0345c2be0d
5 changed files with 44 additions and 39 deletions

6
api.go
View File

@@ -6,19 +6,19 @@ func newConn(module api.Module) *Conn {
getFun := func(name string) api.Function {
f := module.ExportedFunction(name)
if f == nil {
panic("sqlite3: could not find " + name + " function")
panic(noFuncErr + errorString(name))
}
return f
}
global := module.ExportedGlobal("malloc_destructor")
if global == nil {
panic("sqlite3: could not find malloc_destructor global")
panic(noGlobalErr + "malloc_destructor")
}
destructor := uint32(global.Get())
destructor, ok := module.Memory().ReadUint32Le(destructor)
if !ok {
panic("sqlite3: could not read malloc_destructor global")
panic(noGlobalErr + "malloc_destructor")
}
return &Conn{

14
conn.go
View File

@@ -184,7 +184,7 @@ func (c *Conn) new(len uint32) uint32 {
panic(err)
}
if r[0] == 0 {
panic("sqlite3: out of memory")
panic(oomErr)
}
return uint32(r[0])
}
@@ -199,7 +199,7 @@ func (c *Conn) newBytes(s []byte) uint32 {
mem, ok := c.memory.Read(ptr, siz)
if !ok {
c.api.free.Call(c.ctx, uint64(ptr))
panic("sqlite3: out of range")
panic(rangeErr)
}
copy(mem, s)
@@ -212,7 +212,7 @@ func (c *Conn) newString(s string) uint32 {
mem, ok := c.memory.Read(ptr, siz)
if !ok {
c.api.free.Call(c.ctx, uint64(ptr))
panic("sqlite3: out of range")
panic(rangeErr)
}
mem[len(s)] = 0
@@ -227,15 +227,13 @@ func (c *Conn) getString(ptr, maxlen uint32) string {
func getString(memory api.Memory, ptr, maxlen uint32) string {
mem, ok := memory.Read(ptr, maxlen)
if !ok {
if size := memory.Size(); ptr < size {
mem, ok = memory.Read(ptr, size-ptr)
}
mem, ok = memory.Read(ptr, memory.Size()-ptr)
if !ok {
panic("sqlite3: out of range")
panic(rangeErr)
}
}
if i := bytes.IndexByte(mem, 0); i < 0 {
panic("sqlite3: missing NUL terminator")
panic(noNulErr)
} else {
return string(mem[:i])
}

View File

@@ -30,3 +30,15 @@ func (e Error) Error() string {
return b.String()
}
type errorString string
func (e errorString) Error() string { return string(e) }
const (
oomErr = errorString("sqlite3: out of memory")
rangeErr = errorString("sqlite3: index out of range")
noNulErr = errorString("sqlite3: missing NUL terminator")
noGlobalErr = errorString("sqlite3: could not find global: ")
noFuncErr = errorString("sqlite3: could not find function: ")
)

View File

@@ -153,7 +153,7 @@ func (s *Stmt) ColumnText(col int) string {
mem, ok := s.c.memory.Read(ptr, uint32(r[0]))
if !ok {
panic("sqlite3: out of range")
panic(rangeErr)
}
return string(mem)
}
@@ -179,7 +179,7 @@ func (s *Stmt) ColumnBlob(col int, buf []byte) int {
mem, ok := s.c.memory.Read(ptr, uint32(r[0]))
if !ok {
panic("sqlite3: out of range")
panic(rangeErr)
}
return copy(mem, buf)
}

47
vfs.go
View File

@@ -54,7 +54,7 @@ func vfsExit(ctx context.Context, mod api.Module, exitCode uint32) {
func vfsRandomness(ctx context.Context, mod api.Module, vfs, nByte, zOut uint32) uint32 {
mem, ok := mod.Memory().Read(zOut, nByte)
if !ok {
return 0
panic(rangeErr)
}
n, _ := rand.Read(mem)
return uint32(n)
@@ -67,9 +67,8 @@ func vfsSleep(ctx context.Context, vfs, microseconds uint32) uint32 {
func vfsCurrentTime(ctx context.Context, mod api.Module, vfs, out uint32) uint32 {
day := julianday.Float(time.Now())
ok := mod.Memory().WriteFloat64Le(out, day)
if !ok {
return uint32(ERROR)
if ok := mod.Memory().WriteFloat64Le(out, day); !ok {
panic(rangeErr)
}
return _OK
}
@@ -77,9 +76,8 @@ func vfsCurrentTime(ctx context.Context, mod api.Module, vfs, out uint32) uint32
func vfsCurrentTime64(ctx context.Context, mod api.Module, vfs, out uint32) uint32 {
day, nsec := julianday.Date(time.Now())
msec := day*86_400_000 + nsec/1_000_000
ok := mod.Memory().WriteUint64Le(out, uint64(msec))
if !ok {
return uint32(ERROR)
if ok := mod.Memory().WriteUint64Le(out, uint64(msec)); !ok {
panic(rangeErr)
}
return _OK
}
@@ -92,12 +90,12 @@ func vfsFullPathname(ctx context.Context, mod api.Module, vfs, zName, nOut, zOut
}
siz := uint32(len(s) + 1)
if siz > zOut {
if siz > nOut {
return uint32(IOERR)
}
mem, ok := mod.Memory().Read(zOut, siz)
if !ok {
return uint32(IOERR)
panic(rangeErr)
}
mem[len(s)] = 0
@@ -160,9 +158,8 @@ func vfsAccess(ctx context.Context, mod api.Module, vfs, zName, flags, pResOut u
return uint32(IOERR_ACCESS)
}
ok := mod.Memory().WriteUint32Le(pResOut, res)
if !ok {
panic("sqlite: out-of-range")
if ok := mod.Memory().WriteUint32Le(pResOut, res); !ok {
panic(rangeErr)
}
return _OK
}
@@ -201,9 +198,8 @@ func vfsOpen(ctx context.Context, mod api.Module, vfs, zName, file, flags, pOutF
c.files = append(c.files, f)
found:
ok := mod.Memory().WriteUint32Le(file+ptrSize, uint32(id))
if !ok {
panic("sqlite: out-of-range")
if ok := mod.Memory().WriteUint32Le(file+ptrSize, uint32(id)); !ok {
panic(rangeErr)
}
return _OK
}
@@ -211,7 +207,7 @@ found:
func vfsClose(ctx context.Context, mod api.Module, file uint32) uint32 {
id, ok := mod.Memory().ReadUint32Le(file + ptrSize)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
c := ctx.Value(connContext{}).(*Conn)
@@ -226,12 +222,12 @@ func vfsClose(ctx context.Context, mod api.Module, file uint32) uint32 {
func vfsRead(ctx context.Context, mod api.Module, file, buf, iAmt uint32, iOfst uint64) uint32 {
id, ok := mod.Memory().ReadUint32Le(file + ptrSize)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
mem, ok := mod.Memory().Read(buf, iAmt)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
c := ctx.Value(connContext{}).(*Conn)
@@ -251,12 +247,12 @@ func vfsRead(ctx context.Context, mod api.Module, file, buf, iAmt uint32, iOfst
func vfsWrite(ctx context.Context, mod api.Module, file, buf, iAmt uint32, iOfst uint64) uint32 {
id, ok := mod.Memory().ReadUint32Le(file + ptrSize)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
mem, ok := mod.Memory().Read(buf, iAmt)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
c := ctx.Value(connContext{}).(*Conn)
@@ -270,7 +266,7 @@ func vfsWrite(ctx context.Context, mod api.Module, file, buf, iAmt uint32, iOfst
func vfsTruncate(ctx context.Context, mod api.Module, file uint32, size uint64) uint32 {
id, ok := mod.Memory().ReadUint32Le(file + ptrSize)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
c := ctx.Value(connContext{}).(*Conn)
@@ -284,7 +280,7 @@ func vfsTruncate(ctx context.Context, mod api.Module, file uint32, size uint64)
func vfsSync(ctx context.Context, mod api.Module, file, flags uint32) uint32 {
id, ok := mod.Memory().ReadUint32Le(file + ptrSize)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
c := ctx.Value(connContext{}).(*Conn)
@@ -298,7 +294,7 @@ func vfsSync(ctx context.Context, mod api.Module, file, flags uint32) uint32 {
func vfsFileSize(ctx context.Context, mod api.Module, file, pSize uint32) uint32 {
id, ok := mod.Memory().ReadUint32Le(file + ptrSize)
if !ok {
panic("sqlite: out-of-range")
panic(rangeErr)
}
c := ctx.Value(connContext{}).(*Conn)
@@ -307,9 +303,8 @@ func vfsFileSize(ctx context.Context, mod api.Module, file, pSize uint32) uint32
return uint32(IOERR_SEEK)
}
ok = mod.Memory().WriteUint64Le(pSize, uint64(off))
if !ok {
panic("sqlite: out-of-range")
if ok := mod.Memory().WriteUint64Le(pSize, uint64(off)); !ok {
panic(rangeErr)
}
return _OK
}