untgz and gunzip: report unexpected end-of-file

Report an explicit "unexpected end-of-file" error instead of
a later contract failure on #<eof> insteda of a byte

Closes #1204
This commit is contained in:
Matthew Flatt 2016-04-17 15:51:24 -06:00
parent 734d81fed1
commit 027dd9a43c
2 changed files with 27 additions and 19 deletions

View File

@ -54,7 +54,7 @@
used if the block codes up smaller that way (usually for quite small
chunks), otherwise the dynamic method is used. In the latter case, the
codes are customized to the probabilities in the current block, and so
can code it much better than the pre-determined fixed codes.
< can code it much better than the pre-determined fixed codes.
The Huffman codes themselves are decoded using a mutli-level table
lookup, in order to maximize the speed of decoding plus the speed of
@ -208,6 +208,12 @@
(define-const BMAX 16) ; /* maximum bit length of any code (16 for explode) */
(define-const N_MAX 288) ; /* maximum number of codes in any set */
(define (read-byte/not-eof in)
(define b (read-byte in))
(when (eof-object? b)
(error 'inflate "unexpected end-of-file\n stream: ~e" in))
b)
(define (inflate input-port output-port)
(define slide (make-bytes WSIZE))
@ -864,14 +870,14 @@
(arithmetic-shift d 24))]))
(define (do-gunzip in out name-filter)
(let ([header1 (read-byte in)]
[header2 (read-byte in)])
(let ([header1 (read-byte/not-eof in)]
[header2 (read-byte/not-eof in)])
(unless (and (= header1 #o037) (= header2 #o213))
(error 'gnu-unzip "bad header")))
(let ([compression-type (read-byte in)])
(let ([compression-type (read-byte/not-eof in)])
(unless (= compression-type #o010)
(error 'gnu-unzip "unknown compression type")))
(let* ([flags (read-byte in)]
(let* ([flags (read-byte/not-eof in)]
[ascii? (positive? (bitwise-and flags #b1))]
[continuation? (positive? (bitwise-and flags #b10))]
[has-extra-field? (positive? (bitwise-and flags #b100))]
@ -882,23 +888,23 @@
(error 'gnu-unzip "cannot unzip encrypted file"))
(when continuation?
(error 'gnu-unzip "cannot handle multi-part files"))
(let ([unix-mod-time (make-small-endian (read-byte in) (read-byte in)
(read-byte in) (read-byte in))]
[extra-flags (read-byte in)]
[source-os (read-byte in)])
(let ([unix-mod-time (make-small-endian (read-byte/not-eof in) (read-byte/not-eof in)
(read-byte/not-eof in) (read-byte/not-eof in))]
[extra-flags (read-byte/not-eof in)]
[source-os (read-byte/not-eof in)])
(when continuation?
(let ([part-number (make-small-endian (read-byte in) (read-byte in))])
(let ([part-number (make-small-endian (read-byte/not-eof in) (read-byte/not-eof in))])
'ok))
(when has-extra-field?
(let ([len (make-small-endian (read-byte in) (read-byte in))])
(let ([len (make-small-endian (read-byte/not-eof in) (read-byte/not-eof in))])
(let loop ([len len])
(unless (zero? len)
(read-byte in)
(read-byte/not-eof in)
(loop (sub1 len))))))
(let* ([read-null-term-string
(lambda ()
(let loop ([s null])
(let ([r (read-byte in)])
(let ([r (read-byte/not-eof in)])
(if (zero? r)
(list->bytes (reverse s))
(loop (cons r s))))))]
@ -908,7 +914,7 @@
(when encrypted?
(let loop ([n 12])
(unless (zero? n)
(read-byte in)
(read-byte/not-eof in)
(loop (sub1 n)))))
(let-values ([(out close?) (if out

View File

@ -30,8 +30,8 @@
(lambda (in)
(define-values (in2 wait)
(cond
[(and (= (peek-byte in 0) #o037)
(= (peek-byte in 1) #o213))
[(and (= (peek-byte/not-eof in 0) #o037)
(= (peek-byte/not-eof in 1) #o213))
(define-values (in2 out) (make-pipe 4096))
(define t
(thread
@ -49,6 +49,8 @@
(untar in2 #:dest dest #:strip-count strip-count #:permissive? permissive? #:filter filter)
(wait)))))
(define (peek-byte/not-eof in at)
(define b (peek-byte in at))
(when (eof-object? b)
(error 'untgz "unexpected end-of-file\n stream: ~e" in))
b)