From 162045f83154d3df7b482871b05076a92efd02f9 Mon Sep 17 00:00:00 2001 From: Ioannis Kappas Date: Sun, 6 Feb 2022 21:25:56 +0100 Subject: [PATCH] ansi-color: don't get stuck on \e * lisp/ansi-color.el (ansi-color--control-seq-fragment-regexp): New constant. (ansi-color-filter-apply): (ansi-color-apply): (ansi-color-filter-region): (ansi-color-apply-on-region): Don't get stuck on \e if it is determined that it cannot start a valid ANSI escape sequence (Bug#53808). * test/lisp/ansi-color-tests.el (ansi-color-incomplete-sequences-test): Test for \e that doesn't start a valid ANSI escape sequence. --- lisp/ansi-color.el | 26 ++++++++++++++++++++------ test/lisp/ansi-color-tests.el | 20 +++++++++++++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index 3973d9db08..e5d2e2c4ac 100644 --- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -347,6 +347,10 @@ ansi-color-control-seq-regexp "\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,9 @@ ansi-color-filter-apply ;; 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 +555,9 @@ ansi-color-apply (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 +693,11 @@ ansi-color-filter-region (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 +754,12 @@ ansi-color-apply-on-region ;; 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 71b706c763..2ff7fc6aaf 100644 --- a/test/lisp/ansi-color-tests.el +++ b/test/lisp/ansi-color-tests.el @@ -171,7 +171,25 @@ ansi-color-incomplete-sequences-test (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) -- 2.34.1