From d94a1cf079ba4193ca499ba677ba415e0704c71f Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Fri, 13 Sep 2013 17:58:44 -0400 Subject: [PATCH] make odbc-drivers more tolerant of bad attr strings --- pkgs/db-pkgs/db-lib/db/private/odbc/main.rkt | 44 +++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/pkgs/db-pkgs/db-lib/db/private/odbc/main.rkt b/pkgs/db-pkgs/db-lib/db/private/odbc/main.rkt index 37ecc53af0..f31a8e55b2 100644 --- a/pkgs/db-pkgs/db-lib/db/private/odbc/main.rkt +++ b/pkgs/db-pkgs/db-lib/db/private/odbc/main.rkt @@ -75,38 +75,32 @@ (handle-status* 'odbc-data-sources (SQLFreeHandle SQL_HANDLE_ENV env)))))) (define (odbc-drivers) - (define driver-buf (make-bytes 1024)) + (define driver-buf (make-bytes 1000)) + (define attr-buf (make-bytes 2000)) (call-with-env 'odbc-drivers (lambda (env) - (let* ([attrlens - (let loop () - (let-values ([(status name attrlen) - (SQLDrivers env SQL_FETCH_NEXT driver-buf #f)]) - (cond [(or (= status SQL_SUCCESS) (= status SQL_SUCCESS_WITH_INFO)) - (cons attrlen (loop))] - [else null])))] ;; SQL_NO_DATA - [attr-buf (make-bytes (+ 1 (apply max 0 attrlens)))] ;; +1 for null terminator - [result - (let loop () - (let-values ([(status name attrlen) ;; & writes to attr-buf - (SQLDrivers env SQL_FETCH_NEXT driver-buf attr-buf)]) - (cond [(or (= status SQL_SUCCESS) (= status SQL_SUCCESS_WITH_INFO)) - (cons (list name (parse-driver-attrs attr-buf attrlen)) - (loop))] - [else null])))]) ;; SQL_NO_DATA + (let ([result + (let loop () + (let-values ([(status name attrlen) ;; & writes to attr-buf + (SQLDrivers env SQL_FETCH_NEXT driver-buf attr-buf)]) + (cond [(or (= status SQL_SUCCESS) (= status SQL_SUCCESS_WITH_INFO)) + (cons (list name (parse-driver-attrs attr-buf attrlen)) + (loop))] + [else null])))]) ;; SQL_NO_DATA (handle-status* 'odbc-drivers (SQLFreeHandle SQL_HANDLE_ENV env)) result)))) (define (parse-driver-attrs buf len) (let* ([attrs (regexp-split #rx#"\0" buf 0 len)]) - (for/list ([p (in-list attrs)] - #:when (positive? (bytes-length p))) - (let* ([s (bytes->string/utf-8 p)] - [m (regexp-match-positions #rx"=" s)]) - (unless m (error/internal 'odbc-drivers "bad attribute syntax: ~e" s)) - (let ([=-pos (caar m)]) - (cons (substring s 0 =-pos) (substring s (+ 1 =-pos)))))))) - + (filter values + (for/list ([p (in-list attrs)] + #:when (positive? (bytes-length p))) + (let* ([s (bytes->string/utf-8 p)] + [m (regexp-match-positions #rx"=" s)]) + ;; Sometimes (eg iodbc on openbsd), returns ill-formatted attr-buf; just discard + (and m + (let ([=-pos (caar m)]) + (cons (substring s 0 =-pos) (substring s (+ 1 =-pos)))))))))) (define odbc-proxy% (class place-proxy-connection%