Subject: Re: bug#53518: 29.0.50; em-extpipe breaks input of sharp-quoted Lisp symbols

From: Sean Whitton <[email-masked]>
Date: Tue, 25 Jan 2022 01:50:35 -0700

Hello again,

On Mon 24 Jan 2022 at 06:39pm -08, Jim Porter wrote:

> I just noticed a small bit of breakage with this. It's no longer 
> possible to refer to Lisp functions in Eshell like so:
>
>    #'upcase
>
> Eshell explicitly supports this construct (see `eshell-lisp-regexp'), 
> though it doesn't appear to be documented in the manual. Currently, this 
> syntax is only occasionally useful, but I'm working on a patch series 
> where it'll likely become a lot more common. My patches will add support 
> for piping to Lisp functions, so that you can do the following, for example:
>
>    $ echo hi | #'upcase
>    HI

Out of curiosity, why is there a need for the sharpquote?  Why not just
'echo hi | upcase'?  Is it to do with requesting the new piping?

> It looks like the breakage in parsing #'upcase is the result of
> `eshell-parse-external-pipeline' trying to skip over args like '*|' 
> (with the quotes). However, it sees the single-quote in #'upcase and 
> then calls `eshell-parse-literal-quote', resulting in the error message:
>
>    Expecting completion of delimiter ' ...

Here is a patch which has `eshell-parse-external-pipeline' try skipping
over sharp-quoted symbols before trying to skip over single-quoted
strings.

-- 
Sean Whitton
>From 8725495cb91ebf831cd623c58f84a4347e6f1651 Mon Sep 17 00:00:00 2001
From: Sean Whitton <[email-masked]>
Date: Mon, 24 Jan 2022 22:39:15 -0700
Subject: [PATCH] Fix input of sharp-quoted symbols in Eshell with em-extpipe

* lisp/eshell/em-extpipe.el (eshell-parse-external-pipeline): Fix
misinterpreting sharp-quoted symbols as the beginning of single-quoted
strings (Bug#53518).  Add protection against a possible infinite loop.
* test/lisp/eshell/em-extpipe-tests.el (em-extpipe-test-17): New test.
---
 lisp/eshell/em-extpipe.el            | 12 +++++++++---
 test/lisp/eshell/em-extpipe-tests.el |  4 ++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/lisp/eshell/em-extpipe.el b/lisp/eshell/em-extpipe.el
index 57aeec38ff..b0f92e41dc 100644
--- a/lisp/eshell/em-extpipe.el
+++ b/lisp/eshell/em-extpipe.el
@@ -97,15 +97,21 @@ eshell-parse-external-pipeline
                    (while (> bound (point))
                      (let* ((found
                              (save-excursion
-                               (re-search-forward "['\"\\]" bound t)))
+                               (re-search-forward
+                                "\\(?:#?'\\|\"\\|\\\\\\)" bound t)))
                             (next (or (and found (match-beginning 0))
                                       bound)))
                        (if (re-search-forward pat next t)
                            (throw 'found (match-beginning 1))
                          (goto-char next)
-                         (while (or (eshell-parse-backslash)
+                         (while (or (eshell-parse-lisp-argument)
+                                    (eshell-parse-backslash)
                                     (eshell-parse-double-quote)
-                                    (eshell-parse-literal-quote)))))))))
+                                    (eshell-parse-literal-quote)))
+                         ;; Guard against an infinite loop if none of
+                         ;; the parsers moved us forward.
+                         (unless (or (> (point) next) (eobp))
+                           (forward-char 1))))))))
            (goto-char (if (and result go) (match-end 0) start))
            result)))
     (unless (or eshell-current-argument eshell-current-quoted)
diff --git a/test/lisp/eshell/em-extpipe-tests.el b/test/lisp/eshell/em-extpipe-tests.el
index 1283b6b361..0879ad5b0c 100644
--- a/test/lisp/eshell/em-extpipe-tests.el
+++ b/test/lisp/eshell/em-extpipe-tests.el
@@ -202,4 +202,8 @@ em-extpipe-test-16
       (eshell-command-result-p input "rab")
       (eshell-command-result-p "echo \"bar\" | rev" "nonsense"))))
 
+;; Confirm we don't break input of sharp-quoted symbols (Bug#53518).
+(em-extpipe-tests--deftest em-extpipe-test-17 "funcall #'upcase foo"
+  (eshell-command-result-p input "FOO"))
+
 ;;; em-extpipe-tests.el ends here
-- 
2.30.2