From e08c7b3adfc13b1edddc5da4f756b0fa9de6f9e4 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Thu, 19 Dec 2024 14:52:25 +0000 Subject: [PATCH] Refactor. --- driver/driver.go | 1 + driver/util.go | 60 ++++++++++++++++++++++++++++++++ driver/util_test.go | 68 ++++++++++++++++++++++++++++++++++++ driver/whitespace.go | 61 -------------------------------- driver/whitespace_test.go | 73 --------------------------------------- 5 files changed, 129 insertions(+), 134 deletions(-) delete mode 100644 driver/whitespace.go delete mode 100644 driver/whitespace_test.go diff --git a/driver/driver.go b/driver/driver.go index b9bb03bb..742f308a 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -274,6 +274,7 @@ func (n *connector) Connect(ctx context.Context) (res driver.Conn, err error) { // if err != nil { // log.Fatal(err) // } +// defer conn.Close() // // err = conn.Raw(func(driverConn any) error { // conn := driverConn.(driver.Conn) diff --git a/driver/util.go b/driver/util.go index 03384115..98758557 100644 --- a/driver/util.go +++ b/driver/util.go @@ -12,3 +12,63 @@ func namedValues(args []driver.Value) []driver.NamedValue { } return named } + +func notWhitespace(sql string) bool { + const ( + code = iota + slash + minus + ccomment + sqlcomment + endcomment + ) + + state := code + for _, b := range ([]byte)(sql) { + if b == 0 { + break + } + + switch state { + case code: + switch b { + case '/': + state = slash + case '-': + state = minus + case ' ', ';', '\t', '\n', '\v', '\f', '\r': + continue + default: + return true + } + case slash: + if b != '*' { + return true + } + state = ccomment + case minus: + if b != '-' { + return true + } + state = sqlcomment + case ccomment: + if b == '*' { + state = endcomment + } + case sqlcomment: + if b == '\n' { + state = code + } + case endcomment: + switch b { + case '/': + state = code + case '*': + state = endcomment + default: + state = ccomment + } + } + } + return state == slash || state == minus +} diff --git a/driver/util_test.go b/driver/util_test.go index d265096f..562d850d 100644 --- a/driver/util_test.go +++ b/driver/util_test.go @@ -1,9 +1,13 @@ package driver import ( + "context" "database/sql/driver" "reflect" "testing" + + _ "github.com/ncruces/go-sqlite3/embed" + _ "github.com/ncruces/go-sqlite3/internal/testcfg" ) func Test_namedValues(t *testing.T) { @@ -16,3 +20,67 @@ func Test_namedValues(t *testing.T) { t.Errorf("got %v, want %v", got, want) } } + +func Fuzz_notWhitespace(f *testing.F) { + f.Add("") + f.Add(" ") + f.Add(";") + f.Add("0") + f.Add("-") + f.Add("-0") + f.Add("--") + f.Add("--0") + f.Add("--\n") + f.Add("--0\n") + f.Add("/0") + f.Add("/*") + f.Add("/*/") + f.Add("/**") + f.Add("/*0") + f.Add("/**/") + f.Add("/***/") + f.Add("/**0/") + f.Add("\v") + f.Add(" \v") + f.Add("\xf0") + f.Add("\000") + + db, err := Open(":memory:") + if err != nil { + f.Fatal(err) + } + defer db.Close() + + f.Fuzz(func(t *testing.T, str string) { + if len(str) > 128 { + t.SkipNow() + } + + c, err := db.Conn(context.Background()) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + 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 + }) + }) +} diff --git a/driver/whitespace.go b/driver/whitespace.go deleted file mode 100644 index 8f45706f..00000000 --- a/driver/whitespace.go +++ /dev/null @@ -1,61 +0,0 @@ -package driver - -func notWhitespace(sql string) bool { - const ( - code = iota - slash - minus - ccomment - sqlcomment - endcomment - ) - - state := code - for _, b := range ([]byte)(sql) { - if b == 0 { - break - } - - switch state { - case code: - switch b { - case '/': - state = slash - case '-': - state = minus - case ' ', ';', '\t', '\n', '\v', '\f', '\r': - continue - default: - return true - } - case slash: - if b != '*' { - return true - } - state = ccomment - case minus: - if b != '-' { - return true - } - state = sqlcomment - case ccomment: - if b == '*' { - state = endcomment - } - case sqlcomment: - if b == '\n' { - state = code - } - case endcomment: - switch b { - case '/': - state = code - case '*': - state = endcomment - default: - state = ccomment - } - } - } - return state == slash || state == minus -} diff --git a/driver/whitespace_test.go b/driver/whitespace_test.go deleted file mode 100644 index 734f6f71..00000000 --- a/driver/whitespace_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package driver - -import ( - "context" - "testing" - - _ "github.com/ncruces/go-sqlite3/embed" - _ "github.com/ncruces/go-sqlite3/internal/testcfg" -) - -func Fuzz_notWhitespace(f *testing.F) { - f.Add("") - f.Add(" ") - f.Add(";") - f.Add("0") - f.Add("-") - f.Add("-0") - f.Add("--") - f.Add("--0") - f.Add("--\n") - f.Add("--0\n") - f.Add("/0") - f.Add("/*") - f.Add("/*/") - f.Add("/**") - f.Add("/*0") - f.Add("/**/") - f.Add("/***/") - f.Add("/**0/") - f.Add("\v") - f.Add(" \v") - f.Add("\xf0") - f.Add("\000") - - db, err := Open(":memory:") - if err != nil { - f.Fatal(err) - } - defer db.Close() - - f.Fuzz(func(t *testing.T, str string) { - if len(str) > 128 { - t.SkipNow() - } - - c, err := db.Conn(context.Background()) - if err != nil { - t.Fatal(err) - } - defer c.Close() - - 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 - }) - }) -}