Skip to content

Commit c719e20

Browse files
authored
Merge pull request #1392 from mattn/fix-issue-1390-query-comment-panic
Fix panic when querying input with no SQL (only comments/whitespace)
2 parents 58e032d + 869e516 commit c719e20

2 files changed

Lines changed: 61 additions & 6 deletions

File tree

sqlite3.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,25 +1017,37 @@ func (c *SQLiteConn) query(ctx context.Context, query string, args []driver.Name
10171017
if err != nil {
10181018
return nil, err
10191019
}
1020-
s.(*SQLiteStmt).cls = true
1020+
ss := s.(*SQLiteStmt)
1021+
ss.cls = true
1022+
// sqlite3_prepare_v2 returns SQLITE_OK with a NULL statement handle
1023+
// when the input is empty or contains only whitespace/comments.
1024+
if ss.s == nil {
1025+
tail := ss.t
1026+
ss.Close()
1027+
if tail == "" {
1028+
return &SQLiteRows{cls: true, ctx: ctx}, nil
1029+
}
1030+
query = tail
1031+
continue
1032+
}
10211033
na := s.NumInput()
10221034
if len(args)-start < na {
1023-
s.Close()
1035+
ss.Close()
10241036
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start)
10251037
}
10261038
stmtArgs := stmtArgs(args, start, na)
1027-
rows, err := s.(*SQLiteStmt).query(ctx, stmtArgs)
1039+
rows, err := ss.query(ctx, stmtArgs)
10281040
if err != nil && err != driver.ErrSkip {
1029-
s.Close()
1041+
ss.Close()
10301042
return rows, err
10311043
}
10321044
start += na
1033-
tail := s.(*SQLiteStmt).t
1045+
tail := ss.t
10341046
if tail == "" {
10351047
return rows, nil
10361048
}
10371049
rows.Close()
1038-
s.Close()
1050+
ss.Close()
10391051
query = tail
10401052
}
10411053
}
@@ -2441,6 +2453,9 @@ func (rc *SQLiteRows) Close() error {
24412453

24422454
// Columns return column names.
24432455
func (rc *SQLiteRows) Columns() []string {
2456+
if rc.s == nil {
2457+
return rc.cols
2458+
}
24442459
rc.s.mu.Lock()
24452460
defer rc.s.mu.Unlock()
24462461
if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
@@ -2464,13 +2479,19 @@ func (rc *SQLiteRows) declTypes() []string {
24642479

24652480
// DeclTypes return column types.
24662481
func (rc *SQLiteRows) DeclTypes() []string {
2482+
if rc.s == nil {
2483+
return rc.decltype
2484+
}
24672485
rc.s.mu.Lock()
24682486
defer rc.s.mu.Unlock()
24692487
return rc.declTypes()
24702488
}
24712489

24722490
// Next move cursor to next. Attempts to honor context timeout from QueryContext call.
24732491
func (rc *SQLiteRows) Next(dest []driver.Value) error {
2492+
if rc.s == nil {
2493+
return io.EOF
2494+
}
24742495
rc.s.mu.Lock()
24752496
defer rc.s.mu.Unlock()
24762497

sqlite3_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,40 @@ func TestNamedParamClearBindings(t *testing.T) {
20652065
}
20662066
}
20672067

2068+
// https://github.com/mattn/go-sqlite3/issues/1390
2069+
// sqlite3_prepare_v2 returns SQLITE_OK with a NULL statement handle when the
2070+
// input contains no SQL (only whitespace or comments). Querying such input
2071+
// must not panic.
2072+
func TestQueryCommentOnly(t *testing.T) {
2073+
db, err := sql.Open("sqlite3", ":memory:")
2074+
if err != nil {
2075+
t.Fatal(err)
2076+
}
2077+
defer db.Close()
2078+
2079+
cases := []string{"", " ", "-- comment", "---- comment\n", "/* block */"}
2080+
for _, q := range cases {
2081+
var x int
2082+
if err := db.QueryRow(q).Scan(&x); err != sql.ErrNoRows {
2083+
t.Errorf("QueryRow(%q): expected ErrNoRows, got %v", q, err)
2084+
}
2085+
2086+
rows, err := db.Query(q)
2087+
if err != nil {
2088+
t.Errorf("Query(%q): unexpected error: %v", q, err)
2089+
continue
2090+
}
2091+
if rows.Next() {
2092+
t.Errorf("Query(%q): expected no rows", q)
2093+
}
2094+
rows.Close()
2095+
2096+
if _, err := db.Exec(q); err != nil {
2097+
t.Errorf("Exec(%q): unexpected error: %v", q, err)
2098+
}
2099+
}
2100+
}
2101+
20682102
var customFunctionOnce sync.Once
20692103

20702104
func BenchmarkCustomFunctions(b *testing.B) {

0 commit comments

Comments
 (0)