Subject: bug#13350: 24.2; term.el is confused when bash prints almost 4096 bytes

From: [email-masked]
Date: Wed, 28 Dec 2016 21:20:38 -0500

tags 13350 patch
quit

Johan Claesson <[email-masked]> writes:

> emacs -Q
> M-x ansi-term
> /bin/bash
> cd /tmp
> printf '%4090s' x
>
> On my system this gives the error message:
>
> error in process filter: No such directory found via CDPATH environment variable
>
> I think the following is happening:
>
> - Bash will after each command send ?\032 and the current directory
>   "/tmp" to inform term.el. 
> - Bash output is buffered in 4096 bytes chunks.  The end of the first
>   chunk will be "/tm"
> - term.el interprets "/tm" as the current directory and tries to cd
>   there.  Since /tm does not exist it signals an error.
>

Yes, by doing M-x trace-function RET term-emulate-terminal RET, it's
easy to see the chunking.

> I don't know if this buffer size of 4096 varies from system to system.
> In that case maybe the above recipe will not trigger the error on all
> systems. 
>

I needed to use printf '%4088s' x, not sure why the difference.
 
> The following term.el patch is an attempt to fix this:

Patch looks good.  I will push to master in a week or so, unless there
are objections (I added a commit message, see attached).

>From 6660c98d36dbe39e12906a6d02f1faff22c95590 Mon Sep 17 00:00:00 2001
From: Johan Claesson <[email-masked]>
Date: Wed, 28 Dec 2016 12:56:11 -0500
Subject: [PATCH v1] Fix term.el handling of ^Z-sequences spanning chunks

Bash will after each command send ?\032 and the current directory "/tmp"
to inform term.el.  Bash output is buffered in 4096 bytes chunks.  If a
command outputs roughly 4096 bytes then the end of the first chunk will
be "/tm" (Bug#13350).

* lisp/term.el (term-emulate-terminal): Change the regexp to find the
end of the ?\032 sequence to use \n instead of $, the latter can match
end of string as well.

Copyright-paperwork-exempt: yes
---
 lisp/term.el | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lisp/term.el b/lisp/term.el
index a4c652b..d3d6390 100644
--- a/lisp/term.el
+++ b/lisp/term.el
@@ -2880,12 +2880,12 @@ term-emulate-terminal
 			  (beep t))
 			 ((and (eq char ?\032)
                                (not handled-ansi-message))
-			  (let ((end (string-match "\r?$" str i)))
+			  (let ((end (string-match "\r?\n" str i)))
 			    (if end
 				(funcall term-command-hook
 					 (decode-coding-string
 					  (prog1 (substring str (1+ i) end)
-					    (setq i (match-end 0)))
+					    (setq i (1- (match-end 0))))
 					  locale-coding-system))
 			      (setq term-terminal-parameter (substring str i))
 			      (setq term-terminal-state 4)
-- 
2.9.3