file/gunzip: fix problem with lookahead handling

If less than the lookahead bytes have been pulled in, then the
old code would attempt to read a negative number of bytes.
This commit is contained in:
Matthew Flatt 2013-04-24 09:57:47 -06:00
parent fd883dbf32
commit 2dc6b2f87f

View File

@ -255,9 +255,9 @@
|# |#
;; We can't read the bytes outright, because we may ;; We can't read the bytes outright, because we may
;; look ahead. Assume that we need no more than 32 bytes ;; look ahead. Assume that we need no more than 8 bytes
;; look ahead, and peek in 4096-byte blocks. ;; look ahead, and peek in 4096-byte blocks.
(define MAX-LOOKAHEAD 32) (define MAX-LOOKAHEAD 8)
(define BUFFER-SIZE 4096) (define BUFFER-SIZE 4096)
(define buffer (make-bytes BUFFER-SIZE)) (define buffer (make-bytes BUFFER-SIZE))
(define buf-max 0) ; number of bytes in buffer (define buf-max 0) ; number of bytes in buffer
@ -273,13 +273,21 @@
(if (= buf-pos buf-max) (if (= buf-pos buf-max)
(begin (begin
(when (positive? buf-max) (when (positive? buf-max)
(read-bytes! buffer input-port 0 (- buf-max MAX-LOOKAHEAD)) ;; Read consumed bytes, except for the last MAX-LOOKAHEAD bytes,
; (bytes-copy! buffer 0 buffer (- buf-max MAX-LOOKAHEAD) buf-max) ;; which we might unwind:
(set! buf-pos MAX-LOOKAHEAD)) (read-bytes! buffer input-port 0 (max 0 (- buf-max MAX-LOOKAHEAD)))
;; Even though we won't actually use bytes that we "unwind",
;; setting `buf-pos' to the number of unwound bytes lets us
;; keep track of how much to not actually read at the end.
(set! buf-pos (min MAX-LOOKAHEAD buf-max)))
;; Peek (not read) some available bytes:
(let ([got (peek-bytes-avail! buffer buf-pos #f input-port buf-pos BUFFER-SIZE)]) (let ([got (peek-bytes-avail! buffer buf-pos #f input-port buf-pos BUFFER-SIZE)])
(if (eof-object? got) (if (eof-object? got)
(begin (bytes-set! buffer buf-pos 255) ;; Treat an EOF as a -1 "byte":
(begin
(bytes-set! buffer buf-pos 255)
(set! buf-max (add1 buf-pos))) (set! buf-max (add1 buf-pos)))
;; Got normal bytes:
(set! buf-max (+ buf-pos got)))) (set! buf-max (+ buf-pos got))))
(READBITS n)) (READBITS n))
(let ([v (bytes-ref buffer buf-pos)]) (let ([v (bytes-ref buffer buf-pos)])
@ -842,7 +850,7 @@
(set! bk (- bk 8)) (set! bk (- bk 8))
(set! buf-pos (sub1 buf-pos)) (set! buf-pos (sub1 buf-pos))
(loop))) (loop)))
(read-bytes! buffer input-port 0 buf-pos) (read-bytes! buffer input-port 0 buf-pos) ; read consumed bytes
(flush-output wp) (flush-output wp)
#t = (void))) #t = (void)))
#f)))) #f))))