From aa5437493b1ca539409495ecdc54cf420ea110b9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sun, 18 Jul 2021 20:32:49 +0200 Subject: [PATCH] Off-by-one error in compilation rule end-column function (bug#49624) * lisp/progmodes/compile.el (compilation-error-properties): When the end-column parameter of a compilation message rule (in compilation-error-regexp-alist[-alist]) is a function, treat its return value as if it were matched by the regexp, which is how it is documented to work, and how all other parameters work. --- lisp/progmodes/compile.el | 13 ++++++++----- test/lisp/progmodes/compile-tests.el | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index e4363e11b81..02d1c588589 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -1248,11 +1248,14 @@ POS and RES.") (setq col (match-string-no-properties col)) (string-to-number col)))) (setq end-col - (or (if (functionp end-col) (funcall end-col) - (and end-col - (setq end-col (match-string-no-properties end-col)) - (- (string-to-number end-col) -1))) - (and end-line -1))) + (let ((ec (if (functionp end-col) + (funcall end-col) + (and end-col (match-beginning end-col) + (string-to-number + (match-string-no-properties end-col)))))) + (if ec + (1+ ec) ; Add one to get an exclusive upper bound. + (and end-line -1)))) (if (consp type) ; not a static type, check what it is. (setq type (or (and (car type) (match-end (car type)) 1) (and (cdr type) (match-end (cdr type)) 0) diff --git a/test/lisp/progmodes/compile-tests.el b/test/lisp/progmodes/compile-tests.el index 0623cec5285..2a3bb3dafae 100644 --- a/test/lisp/progmodes/compile-tests.el +++ b/test/lisp/progmodes/compile-tests.el @@ -515,4 +515,31 @@ The test data is in `compile-tests--grep-regexp-testcases'." (compile--test-error-line testcase)) (should (eq compilation-num-errors-found 8)))) +(ert-deftest compile-test-functions () + "Test rules using functions instead of regexp group numbers." + (let* ((file-fun (lambda () '("my-file"))) + (line-start-fun (lambda () 123)) + (line-end-fun (lambda () 134)) + (col-start-fun (lambda () 39)) + (col-end-fun (lambda () 24)) + (compilation-error-regexp-alist-alist + `((my-rule + ,(rx bol "My error message") + ,file-fun + (,line-start-fun . ,line-end-fun) + (,col-start-fun . ,col-end-fun)))) + (compilation-error-regexp-alist '(my-rule))) + (with-temp-buffer + (font-lock-mode -1) + (let ((compilation-num-errors-found 0) + (compilation-num-warnings-found 0) + (compilation-num-infos-found 0)) + (compile--test-error-line + '(my-rule + "My error message" + 1 (39 . 24) (123 . 134) "my-file" 2)) + (should (eq compilation-num-errors-found 1)) + (should (eq compilation-num-warnings-found 0)) + (should (eq compilation-num-infos-found 0)))))) + ;;; compile-tests.el ends here -- 2.39.2