Fix infloop in 'shell-resync-dirs'
authorEli Zaretskii <eliz@gnu.org>
Fri, 12 Jul 2024 06:58:53 +0000 (09:58 +0300)
committerEli Zaretskii <eliz@gnu.org>
Fri, 12 Jul 2024 06:58:53 +0000 (09:58 +0300)
* lisp/shell.el (shell-eval-command): Fix detection of newline
after last output line.  (Bug#71896)
(shell-resync-dirs): Make sure the inner loop never infloops.
Suggested by Troy Hinckley <troyhinckley@dabrev.com>.

lisp/shell.el

index e1936ff111966803ebdb0603c6653d5056f8bfe0..4d92fe71df4f31cd03f857f990875bf21f578370 100644 (file)
@@ -1255,7 +1255,7 @@ line output and parses it to form the new directory stack."
     (while dlsl
       (let ((newelt "")
             tem1 tem2)
-        (while newelt
+        (while (and dlsl newelt)
           ;; We need tem1 because we don't want to prepend
           ;; `comint-file-name-prefix' repeatedly into newelt via tem2.
           (setq tem1 (pop dlsl)
@@ -1629,10 +1629,14 @@ Returns t if successful."
           ;; a newline).  This is far from fool-proof -- if something
           ;; outputs incomplete data and then sleeps, we'll think
           ;; we've received the prompt.
-          (while (not (let* ((lines (string-lines result))
-                             (last (car (last lines))))
+          (while (not (let* ((lines (string-lines result nil t))
+                             (last (car (last lines)))
+                             (last-end (if (equal last "")
+                                           last
+                                         (substring last -1))))
                         (and (length> lines 0)
-                             (not (equal last ""))
+                             (not (member last '("" "\n")))
+                             (not (equal last-end "\n"))
                              (or (not prev)
                                  (not (equal last prev)))
                              (setq prev last))))