From: Noam Postavsky Date: Tue, 6 Feb 2018 18:17:07 +0000 (-0500) Subject: Mention that shell quoting of % on w32 may fail (Bug#19350) X-Git-Tag: emacs-26.1-rc1~243 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2dd273b;p=emacs.git Mention that shell quoting of % on w32 may fail (Bug#19350) * doc/lispref/os.texi (Security Considerations): Mention that quoting of '%' assumes no '^' in variable names. * test/lisp/subr-tests.el (shell-quote-argument-%-on-w32): New test, demonstrating what doesn't work. --- diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 9352a929a7a..42be60449de 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -3042,7 +3042,9 @@ with @samp{-}, or might contain shell metacharacters like @samp{;}. Although functions like @code{shell-quote-argument} can help avoid this sort of problem, they are not panaceas; for example, on a POSIX platform @code{shell-quote-argument} quotes shell metacharacters but -not leading @samp{-}. @xref{Shell Arguments}. Typically it is safer +not leading @samp{-}. On MS-Windows, quoting for @samp{%} assumes +none of the environment variables have @samp{^} in their name. +@xref{Shell Arguments}. Typically it is safer to use @code{call-process} than a subshell. @xref{Synchronous Processes}. And it is safer yet to use builtin Emacs functions; for example, use @code{(rename-file "@var{a}" "@var{b}" t)} instead of diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index efafdcf8325..430d719037f 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -307,5 +307,22 @@ cf. Bug#25477." (should (eq (string-to-char (symbol-name (gensym))) ?g)) (should (eq (string-to-char (symbol-name (gensym "X"))) ?X))) +(ert-deftest shell-quote-argument-%-on-w32 () + "Quoting of `%' in w32 shells isn't perfect. +See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." + :expected-result :failed + (skip-unless (and (fboundp 'w32-shell-dos-semantics) + (w32-shell-dos-semantics))) + (let ((process-environment (append '("ca^=with-caret" + "ca=without-caret") + process-environment))) + ;; It actually results in + ;; without-caret with-caret + (should (equal (shell-command-to-string + (format "echo %s %s" + "%ca%" + (shell-quote-argument "%ca%"))) + "without-caret %ca%")))) + (provide 'subr-tests) ;;; subr-tests.el ends here