From 027dd9a43c349dcab5951a1abfffa33f9e1c3aad Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sun, 17 Apr 2016 15:51:24 -0600 Subject: [PATCH] untgz and gunzip: report unexpected end-of-file Report an explicit "unexpected end-of-file" error instead of a later contract failure on # insteda of a byte Closes #1204 --- racket/collects/file/gunzip.rkt | 34 +++++++++++++++++++-------------- racket/collects/file/untgz.rkt | 12 +++++++----- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/racket/collects/file/gunzip.rkt b/racket/collects/file/gunzip.rkt index 5affb028c2..d1d35f7253 100644 --- a/racket/collects/file/gunzip.rkt +++ b/racket/collects/file/gunzip.rkt @@ -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 diff --git a/racket/collects/file/untgz.rkt b/racket/collects/file/untgz.rkt index 592eef7850..357546214b 100644 --- a/racket/collects/file/untgz.rkt +++ b/racket/collects/file/untgz.rkt @@ -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)