From c15d2f71d4ca568556c98a877eca771337eec5bd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 11 Sep 2015 15:27:22 -0600 Subject: [PATCH] file/untar: fix handling of a broken tar file Closes #1049 --- pkgs/racket-test/tests/file/unpackers.rkt | 16 +++++++++++++++- racket/collects/file/untar.rkt | 9 +++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkgs/racket-test/tests/file/unpackers.rkt b/pkgs/racket-test/tests/file/unpackers.rkt index 23d0fc7a36..43707ce389 100644 --- a/pkgs/racket-test/tests/file/unpackers.rkt +++ b/pkgs/racket-test/tests/file/unpackers.rkt @@ -174,8 +174,22 @@ (define (unzip-tests [preserve-timestamps? #f]) (when zip-exe (test do (run-tests (make-unzip-tests* preserve-timestamps?))))) +(define (untar-of-invalid-tests) + ;; Make sure we don't get an internal error for this misformatted tar file: + (define bad-tar.gz + (bytes-append #"\37\213\b\b!D\363U\0\3test.tar\0\355\321A\n\302@\f\205\341\254=\305\334\240\223qb\316\323" + #"\205]YZl\274\277V\21\334\210(\fR\370\277M\26\t\344\301\213\343\22\235\264\225o\334m\235" + #"\352\226_\347\223h1\257\207\252V\\\262j\325*\311\32\347\272\273,\321\237S\222q8\365\21\357" + #"\357>\3557*\326\376\207ij\371\343\321\277\177\321\377\336r\221T\272\30\347\326\341\350?v\377" + #"\16\1\0\0\0\0\0\0\0\0\0\0\0\0\340'W\327\1)\27\0(\0\0")) + (test (regexp-match? + #rx"^unt" + (with-handlers ([exn? exn-message]) + (untgz (open-input-bytes bad-tar.gz) #:filter (lambda args #f)))))) + (module+ main (tests)) (define (tests) (test do (untar-tests) do (unzip-tests) - do (unzip-tests #t))) + do (unzip-tests #t) + do (untar-of-invalid-tests))) diff --git a/racket/collects/file/untar.rkt b/racket/collects/file/untar.rkt index bce385eb9b..d524d4c1c3 100644 --- a/racket/collects/file/untar.rkt +++ b/racket/collects/file/untar.rkt @@ -162,10 +162,11 @@ ;; traditional: (define skip-tail (- len - (for/or ([i (in-range len 0 -1)]) - (case (integer->char (bytes-ref bstr (sub1 i))) - [(#\space #\nul) #f] - [else i])))) + (or (for/or ([i (in-range len 0 -1)]) + (case (integer->char (bytes-ref bstr (sub1 i))) + [(#\space #\nul) #f] + [else i])) + (error 'untar "bad number ~e at ~a" bstr (file-position in))))) (for/fold ([v 0]) ([i (in-range (- len skip-tail))]) (define b (bytes-ref bstr i)) (if (<= (char->integer #\0) b (char->integer #\7))