Skip to content

Commit

Permalink
Perform short read filling before err checking
Browse files Browse the repository at this point in the history
Sqlite requires zero'ing any extra space when there's a short read
buffer. In the case that ReadAt returns a short io.EOF, we need
to zero before returning the buffer and error.

I don't think we were ever actually hitting the zeroing code
before.
  • Loading branch information
psanford committed Apr 8, 2023
1 parent bd28ac7 commit cec2227
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions sqlite3vfscgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func goVFSDelete(cvfs *C.sqlite3_vfs, zName *C.char, syncDir C.int) C.int {
// the file given in the second argument is illegal. If SQLITE_OK is
// returned, then non-zero or zero is written into *pResOut to
// indicate whether or not the file is accessible.
//
//export goVFSAccess
func goVFSAccess(cvfs *C.sqlite3_vfs, zName *C.char, cflags C.int, pResOut *C.int) C.int {
vfs := vfsFromC(cvfs)
Expand Down Expand Up @@ -158,6 +159,7 @@ func goVFSSleep(cvfs *C.sqlite3_vfs, microseconds C.int) C.int {

// On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
// cannot be found.
//
//export goVFSCurrentTimeInt64
func goVFSCurrentTimeInt64(cvfs *C.sqlite3_vfs, piNow *C.sqlite3_int64) C.int {
vfs := vfsFromC(cvfs)
Expand Down Expand Up @@ -209,18 +211,21 @@ func goVFSRead(cfile *C.sqlite3_file, buf unsafe.Pointer, iAmt C.int, iOfst C.sq

goBuf := (*[1 << 28]byte)(buf)[:int(iAmt):int(iAmt)]
n, err := file.ReadAt(goBuf, int64(iOfst))
if err == io.EOF {
return errToC(IOErrorShortRead)
} else if err != nil {
return errToC(err)
}

if n < len(goBuf) {
if err == nil {
// io.ReadAt requires an error if n < len(goBuf)
panic("ReadAt invalid semantics: returned n < len(p) but with a nil error")
}
// If xRead() returns SQLITE_IOERR_SHORT_READ it must also fill in the unread portions of the buffer with zeros.
for i := n; i < len(goBuf); i++ {
goBuf[i] = 0
}
}

if err == io.EOF {
return errToC(IOErrorShortRead)
} else if err != nil {
return errToC(err)
}

return sqliteOK
Expand Down

0 comments on commit cec2227

Please sign in to comment.