[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/relint bafb104 3/3: Fix regexp stack overflow when scan
From: |
ELPA Syncer |
Subject: |
[elpa] externals/relint bafb104 3/3: Fix regexp stack overflow when scanning big files |
Date: |
Wed, 3 Nov 2021 16:57:29 -0400 (EDT) |
branch: externals/relint
commit bafb10445fcf00d0600097e40ac94c885878d922
Author: Mattias EngdegÄrd <mattiase@acm.org>
Commit: Mattias EngdegÄrd <mattiase@acm.org>
Fix regexp stack overflow when scanning big files
This error occurred while scanning a file in phps-mode
(phps-mode-parser.el, 17 MiB, about 190000 strings).
The NFA engine in Emacs is simply not clever enough to avoid stack
build-up here; the smart-jump hack only works in more limited cases.
---
relint-test.el | 19 +++++++++++++++++++
relint.el | 10 +++++-----
2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/relint-test.el b/relint-test.el
index 2e00392..8b4bd66 100644
--- a/relint-test.el
+++ b/relint-test.el
@@ -146,3 +146,22 @@ and a path."
("In call to string-match: Unterminated character
alternative"
125 nil "[xy" nil error)))))
(kill-buffer buf))))
+
+(ert-deftest relint-buffer-huge ()
+ ;; Regression test for regexp stack overflow in the scan for ineffective
+ ;; backslashes.
+ (should (equal
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (insert "(message \"hello\\? anyone?\")\n")
+ (insert "(defconst my-const '(")
+ (dotimes (i 200000)
+ (insert (format "%d " i)))
+ (insert "))\n")
+ (insert "(message \"goodbye\\! everyone!\")\n")
+ (let ((text-quoting-style 'grave))
+ (relint-buffer (current-buffer))))
+ '(("Ineffective string escape `\\?'" 16 nil nil nil warning)
+ ("Ineffective string escape `\\!'" 1288960 nil nil nil
warning)))))
+
+(provide 'relint-test)
diff --git a/relint.el b/relint.el
index be8b254..0108e11 100644
--- a/relint.el
+++ b/relint.el
@@ -2260,11 +2260,11 @@ STRING-START is the start of the string literal (first
double quote)."
"Check for misplaced backslashes in the current buffer."
(goto-char (point-min))
(while (not (eobp))
- (when (looking-at (rx (1+ (or (seq "?" (or (seq ?\\ anything)
- (not (any ?\\))))
- (seq "\\" anything)
- (seq ";" (0+ nonl))
- (not (any ?\" ?\; ?? ?\\))))))
+ (while (looking-at (rx (or (+ (not (any ?\" ?\; ?? ?\\)))
+ (seq ";" (0+ nonl))
+ (seq "?" (or (seq ?\\ anything)
+ (not (any ?\\))))
+ (seq "\\" anything))))
(goto-char (match-end 0)))
(when (eq (following-char) ?\")
(let ((string-start (point)))