From: Harald Jörg Date: Thu, 3 Sep 2020 20:11:47 +0000 (+0200) Subject: Fix freeze in cperl-mode when editing a regexp X-Git-Tag: emacs-28.0.90~6263 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=7921b5db1049709a1d4ed143d1f44417d5087dc1;p=emacs.git 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'. --- diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 44579cfd386..e2628c834ce 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -3241,8 +3241,8 @@ Return the error message (if any). Does not work if delimiter is `)'. 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 @@ Works before syntax recognition is done." (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 @@ Works before syntax recognition is done." (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 abb13f25557..1efcad50078 100644 --- a/test/lisp/progmodes/cperl-mode-tests.el +++ b/test/lisp/progmodes/cperl-mode-tests.el @@ -33,6 +33,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) @@ -63,4 +65,25 @@ have a face property." (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