db: fix sqlite3 memory corruption bug

This commit is contained in:
Ryan Culpepper 2011-12-16 19:18:46 -07:00
parent 664245ae69
commit 6742c308d9
2 changed files with 21 additions and 9 deletions

View File

@ -135,13 +135,13 @@
(let*-values ([(db) (get-db fsym)] (let*-values ([(db) (get-db fsym)]
[(prep-status stmt) [(prep-status stmt)
(HANDLE fsym (HANDLE fsym
(let-values ([(prep-status stmt tail) (let-values ([(prep-status stmt tail?)
(sqlite3_prepare_v2 db sql)]) (sqlite3_prepare_v2 db sql)])
(define (free!) (when stmt (sqlite3_finalize stmt))) (define (free!) (when stmt (sqlite3_finalize stmt)))
(when (string=? sql tail) (unless stmt
(free!) (uerror fsym "SQL syntax error in ~e" tail)) (uerror fsym "SQL syntax error in ~e" sql))
(when (not (zero? (string-length tail))) (when tail?
(free!) (uerror fsym "multiple SQL statements given: ~e" tail)) (free!) (uerror fsym "multiple SQL statements given: ~e" sql))
(values prep-status stmt)))]) (values prep-status stmt)))])
(unless stmt (error/internal fsym "prepare failed")) (unless stmt (error/internal fsym "prepare failed"))
(let* ([param-typeids (let* ([param-typeids

View File

@ -36,13 +36,25 @@
;; -- Stmt -- ;; -- Stmt --
(define (copy-buffer buffer)
(let* ([buffer (string->bytes/utf-8 buffer)]
[n (bytes-length buffer)]
[rawcopy (malloc (add1 n) 'atomic-interior)]
[copy (make-sized-byte-string rawcopy n)])
(memcpy copy buffer n)
(ptr-set! rawcopy _byte n 0)
copy))
(define-sqlite sqlite3_prepare_v2 (define-sqlite sqlite3_prepare_v2
(_fun (db zsql) :: (_fun (db sql) ::
(db : _sqlite3_database) (zsql : _string) ((string-utf-8-length zsql) : _int) (db : _sqlite3_database)
(sql-buffer : _bytes = (copy-buffer sql))
((bytes-length sql-buffer) : _int)
;; bad prepare statements set statement to NULL, with no error reported ;; bad prepare statements set statement to NULL, with no error reported
(statement : (_ptr o _sqlite3_statement/null)) (tail : (_ptr o _string)) (statement : (_ptr o _sqlite3_statement/null))
(tail : (_ptr o _bytes)) ;; points into sql-buffer (atomic-interior)
-> (result : _int) -> (result : _int)
-> (values result statement tail))) -> (values result statement (and tail (positive? (bytes-length tail))))))
(define-sqlite sqlite3_finalize (define-sqlite sqlite3_finalize
(_fun _sqlite3_statement (_fun _sqlite3_statement