diff --git a/api.go b/api.go index 62375d1..aa32298 100644 --- a/api.go +++ b/api.go @@ -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{ diff --git a/conn.go b/conn.go index df5816e..203e6e0 100644 --- a/conn.go +++ b/conn.go @@ -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]) } diff --git a/error.go b/error.go index 36b5158..3461017 100644 --- a/error.go +++ b/error.go @@ -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: ") +) diff --git a/stmt.go b/stmt.go index 13df004..0df44b2 100644 --- a/stmt.go +++ b/stmt.go @@ -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) } diff --git a/vfs.go b/vfs.go index e8a015b..2c3f02e 100644 --- a/vfs.go +++ b/vfs.go @@ -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 }