make installers: fix quoting for windows/bash ssh

original commit: fd487b86a316db29d2d03dc6a665beb21f958371
This commit is contained in:
Matthew Flatt 2013-12-24 09:36:25 -06:00
parent cfcbab2719
commit 1e896570e8

View File

@ -231,7 +231,7 @@
(~a "'" (~a "'"
(regexp-replace* #rx"'" arg "'\"'\"'") (regexp-replace* #rx"'" arg "'\"'\"'")
"'")) "'"))
;; windows quiting built into `cmd' aready ;; windows quoting built into `cmd' aready
cmd)))))) cmd))))))
(define (q s) (define (q s)
@ -262,14 +262,31 @@
(define (shell-protect s kind) (define (shell-protect s kind)
(case kind (case kind
[(windows/bash) [(windows/bash)
;; protect Windows arguments to go through bash, where ;; Protect Windows arguments to go through bash, where
;; backslashes must be escaped, but quotes are effectively ;; unquoted backslashes must be escaped, but quotes are effectively
;; preserved by the shell; also, "&&" must be quoted to ;; preserved by the shell, and quoted backslashes should be left
;; parsing by bash ;; alone; also, "&&" must be quoted to avoid parsing by bash
(regexp-replace* "&&" (regexp-replace* "&&"
(regexp-replace* #rx"[\\]" (list->string
s ;; In practice, the following loop is likely to
"\\\\\\0") ;; do nothing, because constructed command lines
;; tend to have only quoted backslashes.
(let loop ([l (string->list s)] [in-quote? #f])
(cond
[(null? l) null]
[(and (equal? #\\ (car l))
(not in-quote?))
(list* #\\ #\\ (loop (cdr l) #f))]
[(and in-quote?
(equal? #\\ (car l))
(pair? (cdr l))
(or (equal? #\" (cadr l))
(equal? #\\ (cadr l))))
(list* #\\ (cadr l) (loop (cddr l) #t))]
[(equal? #\" (car l))
(cons #\" (loop (cdr l) (not in-quote?)))]
[else
(cons (car l) (loop (cdr l) in-quote?))])))
"\"\\&\\&\"")] "\"\\&\\&\"")]
[else s])) [else s]))