From 2ae8d341de4cb9782241348b28e4f713c317925c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20J=C3=B6rg?= Date: Thu, 3 Sep 2020 22:11:47 +0200 Subject: [PATCH] Fix freeze in cperl-mode when editing a regexp * lisp/progmodes/cperl-mode.el (cperl-forward-group-in-re): Make sure that an error is reported back to the caller (Bug#16368). * test/lisp/progmodes/cperl-mode-tests.el (cperl-mode-test-bug-16368): Tests for balanced (no error) and unbalanced (caught exception) cases of `cperl-forward-group-in-re'. --- lisp/progmodes/cperl-mode.el | 9 ++++----- test/lisp/progmodes/cperl-mode-tests.el | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 44579cfd38..e2628c834c 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -3241,8 +3241,8 @@ cperl-forward-group-in-re Works before syntax recognition is done." ;; Works *before* syntax recognition is done (or st-l (setq st-l (list nil))) ; Avoid overwriting '() - (let (st b reset-st) - (condition-case b + (let (st result reset-st) + (condition-case err (progn (setq st (cperl-cached-syntax-table st-l)) (modify-syntax-entry ?\( "()" st) @@ -3250,8 +3250,7 @@ cperl-forward-group-in-re (setq reset-st (syntax-table)) (set-syntax-table st) (forward-sexp 1)) - (error (message - "cperl-forward-group-in-re: error %s" b))) + (error (setq result err))) ;; now restore the initial state (if st (progn @@ -3259,7 +3258,7 @@ cperl-forward-group-in-re (modify-syntax-entry ?\) "." st))) (if reset-st (set-syntax-table reset-st)) - b)) + result)) (defvar font-lock-string-face) diff --git a/test/lisp/progmodes/cperl-mode-tests.el b/test/lisp/progmodes/cperl-mode-tests.el index be8b42d99a..e14ff98e3f 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -18,6 +18,8 @@ (defvar cperl-test-mode #'cperl-mode) +(require 'cperl-mode) + (defun cperl-test-ppss (text regexp) "Return the `syntax-ppss' of the first character matched by REGEXP in TEXT." (interactive) @@ -48,4 +50,25 @@ cperl-mode-test-bug-42168 (let ((code "{ $a- / $b } # /")) (should (equal (nth 8 (cperl-test-ppss code "/")) 7)))) +(ert-deftest cperl-mode-test-bug-16368 () + "Verify that `cperl-forward-group-in-re' doesn't hide errors." + (skip-unless (eq cperl-test-mode #'cperl-mode)) + (let ((code "/(\\d{4})(?{2}/;") ; the regex from the bug report + (result)) + (with-temp-buffer + (insert code) + (goto-char 9) + (setq result (cperl-forward-group-in-re)) + (should (equal (car result) 'scan-error)) + (should (equal (nth 1 result) "Unbalanced parentheses")) + (should (= (point) 9)))) ; point remains unchanged on error + (let ((code "/(\\d{4})(?{2})/;") ; here all parens are balanced + (result)) + (with-temp-buffer + (insert code) + (goto-char 9) + (setq result (cperl-forward-group-in-re)) + (should (equal result nil)) + (should (= (point) 15))))) ; point has skipped the group + ;;; cperl-mode-tests.el ends here -- 2.20.1