~ruther/guix-local

814b099a209f335944737e701cbfcb09ac811d58 — Tobias Geerinckx-Rice 9 years ago 58f91e4
download: Add ‘url-fetch/zipbomb’.

From this suggestion by Ludovic Courtès:
<http://lists.gnu.org/archive/html/guix-devel/2016-09/msg01983.html>

* guix/download.scm (url-fetch/zipbomb): New procedure.
1 files changed, 30 insertions(+), 0 deletions(-)

M guix/download.scm
M guix/download.scm => guix/download.scm +30 -0
@@ 36,6 36,7 @@
  #:export (%mirrors
            url-fetch
            url-fetch/tarbomb
            url-fetch/zipbomb
            download-to-store))

;;; Commentary:


@@ 512,6 513,35 @@ own.  This helper makes it easier to deal with \"tar bombs\"."
                                          "xf" #$drv)))
                      #:local-build? #t)))

(define* (url-fetch/zipbomb url hash-algo hash
                            #:optional name
                            #:key (system (%current-system))
                            (guile (default-guile)))
  "Similar to 'url-fetch' but unpack the zip file at URL in a directory of its
own.  This helper makes it easier to deal with \"zip bombs\"."
  (define file-name
    (match url
      ((head _ ...)
       (basename head))
      (_
       (basename url))))
  (define unzip
    (module-ref (resolve-interface '(gnu packages zip)) 'unzip))

  (mlet %store-monad ((drv (url-fetch url hash-algo hash
                                      (string-append "zipbomb-"
                                                     (or name file-name))
                                      #:system system
                                      #:guile guile)))
    ;; Take the zip bomb, and simply unpack it as a directory.
    (gexp->derivation (or name file-name)
                      #~(begin
                          (mkdir #$output)
                          (chdir #$output)
                          (zero? (system* (string-append #$unzip "/bin/unzip")
                                          #$drv)))
                      #:local-build? #t)))

(define* (download-to-store store url #:optional (name (basename url))
                            #:key (log (current-error-port)) recursive?
                            (verify-certificate? #t))