zlib: Protect against non-empty port internal buffers.

* guix/zlib.scm (make-gzip-input-port)[gzfile]: Error out
if (drain-input port) returns a non-empty string.
* guix/zlib.scm (make-gzip-output-port)[gzfile]: Call 'force-output'.
This commit is contained in:
Ludovic Courtès 2016-07-27 12:39:27 +02:00
parent d00240c36e
commit 688ec13c45
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5

View file

@ -168,9 +168,18 @@ (define* (make-gzip-input-port port #:key (buffer-size %default-buffer-size))
"Return an input port that decompresses data read from PORT, a file port.
PORT is automatically closed when the resulting port is closed. BUFFER-SIZE
is the size in bytes of the internal buffer, 8 KiB by default; using a larger
buffer increases decompression speed."
buffer increases decompression speed. An error is thrown if PORT contains
buffered input, which would be lost (and is lost anyway)."
(define gzfile
(gzdopen (fileno port) "r"))
(match (drain-input port)
("" ;PORT's buffer is empty
(gzdopen (fileno port) "r"))
(_
;; This is unrecoverable but it's better than having the buffered input
;; be lost, leading to unclear end-of-file or corrupt-data errors down
;; the path.
(throw 'zlib-error 'make-gzip-input-port
"port contains buffered input" port))))
(define (read! bv start count)
(gzread! gzfile bv start count))
@ -189,8 +198,10 @@ (define* (make-gzip-output-port port
a file port, as its sink. PORT is automatically closed when the resulting
port is closed."
(define gzfile
(gzdopen (fileno port)
(string-append "w" (number->string level))))
(begin
(force-output port) ;empty PORT's buffer
(gzdopen (fileno port)
(string-append "w" (number->string level)))))
(define (write! bv start count)
(gzwrite gzfile bv start count))