emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c12a48c335: Fix handling of '\\' inside double-quotes in Eshell


From: Lars Ingebrigtsen
Subject: master c12a48c335: Fix handling of '\\' inside double-quotes in Eshell
Date: Sun, 3 Apr 2022 08:17:27 -0400 (EDT)

branch: master
commit c12a48c3350bb5aa2cbefda10c5364c778463366
Author: Jim Porter <jporterbugs@gmail.com>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Fix handling of '\\' inside double-quotes in Eshell
    
    Previously, Eshell would get confused and think the following command
    was unterminated due to the second double-quote looking like it was
    escaped:
    
      echo "\\"
    
    * lisp/eshell/esh-util.el (eshell-find-delimiter): Correct docstring
    and treat '\' as an escapeable character when using backslash escapes.
    
    * test/lisp/eshell/eshell-tests.el
    (eshell-test/escape-special-quoted): Adapt test.
---
 lisp/eshell/esh-util.el          | 51 +++++++++++++++++++++-------------------
 test/lisp/eshell/eshell-tests.el |  4 ++--
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index 788404fc43..8089d4d74b 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -151,49 +151,52 @@ Otherwise, evaluates FORM with no error handling."
 (defun eshell-find-delimiter
   (open close &optional bound reverse-p backslash-p)
   "From point, find the CLOSE delimiter corresponding to OPEN.
-The matching is bounded by BOUND.
-If REVERSE-P is non-nil, process the region backwards.
-If BACKSLASH-P is non-nil, and OPEN and CLOSE are the same character,
-then quoting is done by a backslash, rather than a doubled delimiter."
+The matching is bounded by BOUND. If REVERSE-P is non-nil,
+process the region backwards.
+
+If BACKSLASH-P is non-nil, or OPEN and CLOSE are different
+characters, then a backslash can be used to escape a delimiter
+(or another backslash).  Otherwise, the delimiter is escaped by
+doubling it up."
   (save-excursion
     (let ((depth 1)
          (bound (or bound (point-max))))
-      (if (if reverse-p
-             (eq (char-before) close)
-           (eq (char-after) open))
-         (forward-char (if reverse-p -1 1)))
+      (when (if reverse-p
+                (eq (char-before) close)
+              (eq (char-after) open))
+        (forward-char (if reverse-p -1 1)))
       (while (and (> depth 0)
-                 (funcall (if reverse-p '> '<) (point) bound))
-       (let ((c (if reverse-p (char-before) (char-after))) nc)
+                  (funcall (if reverse-p #'> #'<) (point) bound))
+        (let ((c (if reverse-p (char-before) (char-after))))
          (cond ((and (not reverse-p)
                      (or (not (eq open close))
                          backslash-p)
                      (eq c ?\\)
-                     (setq nc (char-after (1+ (point))))
-                     (or (eq nc open) (eq nc close)))
+                      (memq (char-after (1+ (point)))
+                            (list open close ?\\)))
                 (forward-char 1))
                ((and reverse-p
                      (or (not (eq open close))
                          backslash-p)
-                     (or (eq c open) (eq c close))
-                     (eq (char-before (1- (point)))
-                         ?\\))
+                      (eq (char-before (1- (point))) ?\\)
+                      (memq c (list open close ?\\)))
                 (forward-char -1))
                ((eq open close)
-                (if (eq c open)
-                    (if (and (not backslash-p)
-                             (eq (if reverse-p
-                                     (char-before (1- (point)))
-                                   (char-after (1+ (point)))) open))
-                        (forward-char (if reverse-p -1 1))
-                      (setq depth (1- depth)))))
+                 (when (eq c open)
+                   (if (and (not backslash-p)
+                            (eq (if reverse-p
+                                    (char-before (1- (point)))
+                                  (char-after (1+ (point))))
+                                open))
+                       (forward-char (if reverse-p -1 1))
+                     (setq depth (1- depth)))))
                ((= c open)
                 (setq depth (+ depth (if reverse-p -1 1))))
                ((= c close)
                 (setq depth (+ depth (if reverse-p 1 -1))))))
        (forward-char (if reverse-p -1 1)))
-      (if (= depth 0)
-         (if reverse-p (point) (1- (point)))))))
+      (when (= depth 0)
+        (if reverse-p (point) (1- (point)))))))
 
 (defun eshell-convert (string)
   "Convert STRING into a more native looking Lisp object."
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 1e303f70e5..bcc2dc320b 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -148,9 +148,9 @@ chars"
   "Test that the backslash is not preserved for escaped special
 chars"
   (with-temp-eshell
-   (eshell-command-result-p "echo \"h\\\\i\""
+   (eshell-command-result-p "echo \"\\\"hi\\\\\""
                             ;; Backslashes are doubled for regexp.
-                            "h\\\\i\n")))
+                            "\\\"hi\\\\\n")))
 
 (ert-deftest eshell-test/command-running-p ()
   "Modeline should show no command running"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]