From: Ioannis Kappas Date: Sun, 6 Feb 2022 22:54:07 +0000 (+0100) Subject: ansi-color: don't get stuck on \e X-Git-Tag: emacs-29.0.90~2475 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e9ba08be215f88868d9e8c7ef736b0eb83d6ddff;p=emacs.git ansi-color: don't get stuck on \e * lisp/ansi-color.el (ansi-color--control-seq-fragment-regexp): New constant. * test/lisp/ansi-color-tests.el (ansi-color-incomplete-sequences-test): Test for \e that doesn't start a valid ANSI escape sequence (bug#53808). Code amended (and test code written) by . Code by Ioannis Kappas is small enough to be Copyright-paperwork-exempt: yes --- diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index 3973d9db08e..b273e1f6340 100644 --- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -347,6 +347,10 @@ version of that color." "\e\\[[\x30-\x3F]*[\x20-\x2F]*[\x40-\x7E]" "Regexp matching an ANSI control sequence.") +(defconst ansi-color--control-seq-fragment-regexp + "\e\\[[\x30-\x3F]*[\x20-\x2F]*\\|\e" + "Regexp matching a partial ANSI control sequence.") + (defconst ansi-color-parameter-regexp "\\([0-9]*\\)[m;]" "Regexp that matches SGR control sequence parameters.") @@ -492,7 +496,11 @@ This function can be added to `comint-preoutput-filter-functions'." ;; save context, add the remainder of the string to the result (let ((fragment "")) (push (substring string start - (if (string-match "\033" string start) + (if (string-match + (concat "\\(?:" + ansi-color--control-seq-fragment-regexp + "\\)\\'") + string start) (let ((pos (match-beginning 0))) (setq fragment (substring string pos)) pos) @@ -549,7 +557,9 @@ This function can be added to `comint-preoutput-filter-functions'." (put-text-property start (length string) 'font-lock-face face string)) ;; save context, add the remainder of the string to the result - (if (string-match "\033" string start) + (if (string-match + (concat "\\(?:" ansi-color--control-seq-fragment-regexp "\\)\\'") + string start) (let ((pos (match-beginning 0))) (setcar (cdr context) (substring string pos)) (push (substring string start pos) result)) @@ -685,7 +695,11 @@ it will override BEGIN, the start of the region. Set (while (re-search-forward ansi-color-control-seq-regexp end-marker t) (delete-region (match-beginning 0) (match-end 0))) ;; save context, add the remainder of the string to the result - (if (re-search-forward "\033" end-marker t) + (set-marker start (point)) + (while (re-search-forward ansi-color--control-seq-fragment-regexp + end-marker t)) + (if (and (/= (point) start) + (= (point) end-marker)) (set-marker start (match-beginning 0)) (set-marker start nil))))) @@ -742,10 +756,12 @@ being deleted." ;; Otherwise, strip. (delete-region esc-beg esc-end)))) ;; search for the possible start of a new escape sequence - (if (re-search-forward "\033" end-marker t) + (while (re-search-forward ansi-color--control-seq-fragment-regexp + end-marker t)) + (if (and (/= (point) start-marker) + (= (point) end-marker)) (progn - (while (re-search-forward "\033" end-marker t)) - (backward-char) + (goto-char (match-beginning 0)) (funcall ansi-color-apply-face-function start-marker (point) (ansi-color--face-vec-face face-vec)) diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el index 71b706c763f..2ff7fc6aaf6 100644 --- a/test/lisp/ansi-color-tests.el +++ b/test/lisp/ansi-color-tests.el @@ -171,7 +171,25 @@ strings with `eq', this function compares them with `equal'." (insert str) (ansi-color-apply-on-region opoint (point)))) (should (ansi-color-tests-equal-props - propertized-str (buffer-string)))))) + propertized-str (buffer-string)))) + + ;; \e not followed by '[' and invalid ANSI escape seqences + (dolist (fun (list ansi-filt ansi-app)) + (with-temp-buffer + (should (equal (funcall fun "\e") "")) + (should (equal (funcall fun "\e[33m test \e[0m") + (with-temp-buffer + (concat "\e" (funcall fun "\e[33m test \e[0m")))))) + (with-temp-buffer + (should (equal (funcall fun "\e[") "")) + (should (equal (funcall fun "\e[33m Z \e[0m") + (with-temp-buffer + (concat "\e[" (funcall fun "\e[33m Z \e[0m")))))) + (with-temp-buffer + (should (equal (funcall fun "\e a \e\e[\e[") "\e a \e\e[")) + (should (equal (funcall fun "\e[33m Z \e[0m") + (with-temp-buffer + (concat "\e[" (funcall fun "\e[33m Z \e[0m"))))))))) (provide 'ansi-color-tests)