diff --git a/net-doc/net/scribblings/git-checkout.scrbl b/net-doc/net/scribblings/git-checkout.scrbl index 666b94d66e..46cecaff20 100644 --- a/net-doc/net/scribblings/git-checkout.scrbl +++ b/net-doc/net/scribblings/git-checkout.scrbl @@ -35,7 +35,8 @@ for information on command-line arguments and flags. [#:port port (or/c #f (integer-in 1 65535)) (case transport [(git) 9418] [(http) 80] - [(https) 443])]) + [(https) 443])] + [#:strict-links? strict-links? any/c #f]) string?]{ Contacts the server at @racket[hostname] and @racket[port] @@ -91,5 +92,10 @@ temporary clone of the repository, and the files are preserved unless the shape that is recognized by other tools, such as @exec{git}, and so a preserved temporary directory is useful mainly for debugging. +If @racket[strict-links?] is true, then the checkout fails with an +error if it would produce a symbolic link that refers to an absolute path +or to a relative path that contains up-directory elements. + @history[#:added "6.1.1.1" - #:changed "6.3" @elem{Added the @racket[initial-error] argument.}]} + #:changed "6.3" @elem{Added the @racket[initial-error] argument.} + #:changed "6.2.900.17" @elem{Added the @racket[strict-links?] argument.}]} diff --git a/net-test/tests/net/git-checkout.rkt b/net-test/tests/net/git-checkout.rkt index 134884a18a..8ca1fb6051 100644 --- a/net-test/tests/net/git-checkout.rkt +++ b/net-test/tests/net/git-checkout.rkt @@ -60,47 +60,72 @@ (error 'compare "no such file: ~s" a)])) (when git - (define dir (make-temporary-file "~a-git-test" 'directory)) - (define http-custodian (make-custodian)) - (dynamic-wind - void - (lambda () - (parameterize ([current-custodian http-custodian]) - (thread - (lambda () - (serve/servlet - void - #:command-line? #t - #:extra-files-paths (list dir) - #:servlet-regexp #rx"$." ; no servlets - #:port 8950)))) - - (parameterize ([current-directory dir]) - (make-directory "repo") - (parameterize ([current-directory "repo"]) - (make-file "x" #"hello") - (make-file "y" #"goodbye") - (unless (eq? (system-type) 'windows) - (file-or-directory-permissions "y" #o755)) - (make-file "z" #"whatever") - (unless (eq? (system-type) 'windows) - (file-or-directory-permissions "z" #o644)) - (unless (eq? (system-type) 'windows) - (make-file-or-directory-link "x" "also-x")) - (git "init") - (git "add" ".") - (git "commit" "-m" "initial commit") - (git "update-server-info")) + (for ([link-mode '(rel up abs)]) + (define dir (make-temporary-file "~a-git-test" 'directory)) + (define http-custodian (make-custodian)) + (dynamic-wind + void + (lambda () + (parameterize ([current-custodian http-custodian]) + (thread + (lambda () + (serve/servlet + void + #:command-line? #t + #:extra-files-paths (list dir) + #:servlet-regexp #rx"$." ; no servlets + #:port 8950)))) - (git-checkout "localhost" #:port 8950 #:transport 'http - "repo/.git" - #:dest-dir "also-repo") - - (compare "repo" "also-repo") - - (void))) - (lambda () - (custodian-shutdown-all http-custodian) - (delete-directory/files dir)))) + (parameterize ([current-directory dir]) + (make-directory "repo") + (parameterize ([current-directory "repo"]) + (make-file "x" #"hello") + (make-file "y" #"goodbye") + (unless (eq? (system-type) 'windows) + (file-or-directory-permissions "y" #o755)) + (make-file "z" #"whatever") + (unless (eq? (system-type) 'windows) + (file-or-directory-permissions "z" #o644)) + (make-directory "nested") + (make-file "nested/x" #"stuff") + (unless (eq? (system-type) 'windows) + (case link-mode + [(abs) + (make-file-or-directory-link "/tmp/x" "abs-x")] + [(up) + (make-file-or-directory-link "../x" "abs-x")] + [else + (make-file-or-directory-link "x" "also-x")])) + (git "init") + (git "add" ".") + (git "commit" "-m" "initial commit") + (git "update-server-info")) + + (git-checkout "localhost" #:port 8950 #:transport 'http + "repo/.git" + #:dest-dir "also-repo") + (compare "repo" "also-repo") + + (with-handlers ([exn:fail? + (lambda (exn) + (case link-mode + [(abs up) + (if (regexp-match? #rx"won't extract" (exn-message exn)) + (printf "correct failure\n") + (raise exn))] + [else (raise exn)]))]) + (git-checkout "localhost" #:port 8950 #:transport 'http + "repo/.git" + #:dest-dir "safe-repo" + #:strict-links? #t) + (case link-mode + [(abs up) (unless (eq? 'windows (system-type)) + (error "should not have worked"))]) + (compare "repo" "safe-repo")) + + (void))) + (lambda () + (custodian-shutdown-all http-custodian) + (delete-directory/files dir))))) + -