Skip to content

Commit

Permalink
Fix #201.
Browse files Browse the repository at this point in the history
  • Loading branch information
ncruces committed Dec 12, 2024
1 parent 37f2145 commit 5ed4a6c
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 5 deletions.
2 changes: 1 addition & 1 deletion driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, e
if err != nil {
return nil, err
}
if tail != "" {
if notWhitespace(tail) {
s.Close()
return nil, util.TailErr
}
Expand Down
4 changes: 2 additions & 2 deletions driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ func Test_Prepare(t *testing.T) {
}

_, err = db.Prepare(`SELECT 1; `)
if err.Error() != string(util.TailErr) {
t.Error("want tailErr")
if err != nil {
t.Error(err)
}

_, err = db.Prepare(`SELECT 1; SELECT`)
Expand Down
4 changes: 2 additions & 2 deletions driver/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ func Fuzz_stringOrTime_1(f *testing.F) {
// Make sure times round-trip to the same string:
// https://pkg.go.dev/database/sql#Rows.Scan
if v.Format(time.RFC3339Nano) != str {
t.Fatalf("did not round-trip: %q", str)
t.Errorf("did not round-trip: %q", str)
}
} else {
date, err := time.Parse(time.RFC3339Nano, str)
if err == nil && date.Format(time.RFC3339Nano) == str {
t.Fatalf("would round-trip: %q", str)
t.Errorf("would round-trip: %q", str)
}
}
})
Expand Down
67 changes: 67 additions & 0 deletions driver/whitespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package driver

func notWhitespace(sql string) bool {
const (
code = iota
minus
slash
ccomment
endcomment
sqlcomment
)

state := code
for _, b := range ([]byte)(sql) {
if b == 0 {
break
}

switch state {
case code:
switch b {
case '-':
state = minus
case '/':
state = slash
case ' ', ';', '\t', '\n', '\v', '\f', '\r':
continue
default:
return true
}
case minus:
if b != '-' {
return true
}
state = sqlcomment
case slash:
if b != '*' {
return true
}
state = ccomment
case ccomment:
if b == '*' {
state = endcomment
}
case endcomment:
switch b {
case '/':
state = code
case '*':
state = endcomment
default:
state = ccomment
}
case sqlcomment:
if b == '\n' {
state = code
}
}
}

switch state {
case code, ccomment, endcomment, sqlcomment:
return false
default:
return true
}
}
56 changes: 56 additions & 0 deletions driver/whitespace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package driver

import (
"context"
"testing"
)

func Fuzz_isWhitespace(f *testing.F) {
f.Add("")
f.Add(" ")
f.Add(";")
f.Add("0")
f.Add("-")
f.Add("--")
f.Add("/*")
f.Add("/*/")
f.Add("/**")
f.Add("/**0/")
f.Add("\v")
f.Add(" \v")
f.Add("\xf0")

db, err := Open(":memory:")
if err != nil {
f.Fatal(err)
}
defer db.Close()

f.Fuzz(func(t *testing.T, str string) {
c, err := db.Conn(context.Background())
if err != nil {
t.Fatal(err)
}

c.Raw(func(driverConn any) error {
conn := driverConn.(*conn).Conn
stmt, tail, err := conn.Prepare(str)
stmt.Close()

// It's hard to be bug for bug compatible with SQLite.
// We settle for somewhat less:
// - if SQLite reports whitespace, we must too
// - if we report whitespace, SQLite must not parse a statement
if notWhitespace(str) {
if stmt == nil && tail == "" && err == nil {
t.Errorf("was whitespace: %q", str)
}
} else {
if stmt != nil {
t.Errorf("was not whitespace: %q (%v)", str, err)
}
}
return nil
})
})
}
1 change: 1 addition & 0 deletions vfs/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
osUnlock(file, _SHARED_FIRST, _SHARED_SIZE)

// Acquire the EXCLUSIVE lock.
// Can't wait here, because the file is not OVERLAPPED.
rc := osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, 0)

if rc != _OK {
Expand Down

0 comments on commit 5ed4a6c

Please sign in to comment.