From d7db2aff594cb7f16d55099655062be7e192a7d4 Mon Sep 17 00:00:00 2001 From: Lehi Toskin Date: Mon, 26 Jun 2017 12:48:10 -0700 Subject: [PATCH] net/git-chckout: check ADLER32 after inflate Check ADLER32 after inflate, instead of assuming that the inflated bytes are correct. --- racket/collects/net/git-checkout.rkt | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/racket/collects/net/git-checkout.rkt b/racket/collects/net/git-checkout.rkt index d9e79665a2..99c83d6ff3 100644 --- a/racket/collects/net/git-checkout.rkt +++ b/racket/collects/net/git-checkout.rkt @@ -1081,6 +1081,20 @@ (arithmetic-shift (read-number-by-bits i (arithmetic-shift n -1)) 8))])) +;; ADLER32 implementation +;; https://www.ietf.org/rfc/rfc1950.txt +(define (bytes-adler32 bstr) + (define ADLER 65521) + (define-values (s1 s2) + (for/fold ([s1 1] + [s2 0]) + ([bits (in-bytes bstr)]) + (define a (modulo (+ s1 bits) ADLER)) + (define b (modulo (+ s2 a) ADLER)) + (values a b))) + ; (s2 << 16) | s1 + (bitwise-ior (arithmetic-shift s2 16) s1)) + ;; zlib-inflate : input-port output-port ;; Reads compressed data from `i`, writes uncompressed to `o` (define (zlib-inflate i o) @@ -1091,9 +1105,18 @@ (when (bitwise-bit-set? flg 5) ;; read dictid (read-bytes-exactly 'dictid 4 i)) - (inflate i o) + ;; obtain the uncompressed bytes even if o is a file port + (define intermediate-out (open-output-bytes)) + (inflate i intermediate-out) + (define uncompressed (get-output-bytes intermediate-out)) + (close-output-port intermediate-out) + ;; pass the bytes to o + (display uncompressed o) ;; Verify checksum? - (read-bytes-exactly 'adler-checksum 4 i) + (define adler (read-bytes-exactly 'adler-checksum 4 i)) + (unless (= (integer-bytes->integer adler #f #t) + (bytes-adler32 uncompressed)) + (raise-git-error 'git-checkout "adler32 checksum failed")) (void)) ;; ----------------------------------------