branch: elpa/adoc-mode
commit 0ef1eeac3f1a07ec32337d34dd57be2ac8960c58
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
[Fix #57] Fix Emacs hang on escaped curly braces
The attribute reference regex \w+(?:\w*|-)* had catastrophic
backtracking when matching long hyphenated strings (like UUIDs)
followed by \} instead of }. The overlapping \w+ and \w* quantifiers
caused exponential backtracking on failed matches.
Replace with \w[[:word:]-]* which matches the same strings but uses
a character class with no ambiguity.
---
CHANGELOG.md | 1 +
adoc-mode.el | 2 +-
test/adoc-mode-test.el | 10 ++++++++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5165c15af5..f0a0abf796 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@
- Fix forced line break (`+`) highlighting inside reserved regions.
- Fix backquote/comma usage in `adoc-kw-inline-macro` so `textprops` is
properly substituted.
- Fix duplicate `face` key in `adoc-kw-delimited-block` plist.
+- [#57](https://github.com/bbatsov/adoc-mode/issues/57): Fix Emacs hang on
escaped curly braces in attribute reference regex.
## 0.7.0 (2023-03-09)
diff --git a/adoc-mode.el b/adoc-mode.el
index b5ab2ea05b..0a57a69af7 100644
--- a/adoc-mode.el
+++ b/adoc-mode.el
@@ -2485,7 +2485,7 @@ Use this function as matching function MATCHER in
`font-lock-keywords'."
;; attributes
;; ---------------------------------
;; attribute reference
- (cons "{\\(\\w+\\(?:\\w*\\|-\\)*\\)\\([=?!#%@$][^}\n]*\\)?}"
'adoc-replacement-face)
+ (cons "{\\(\\w[[:word:]-]*\\)\\([=?!#%@$][^}\n]*\\)?}"
'adoc-replacement-face)
;; inline macros (that includes anchors, links, footnotes,....)
diff --git a/test/adoc-mode-test.el b/test/adoc-mode-test.el
index 80384dd186..adad35b594 100644
--- a/test/adoc-mode-test.el
+++ b/test/adoc-mode-test.el
@@ -587,6 +587,16 @@ Don't use it for anything real.")
"[\"" adoc-meta-face "lorem \\\"ipsum\\\" dolor"
adoc-value-face "\"]" adoc-meta-face
))
+;; Regression test for https://github.com/bbatsov/adoc-mode/issues/57
+(ert-deftest adoctest-test-attribute-reference ()
+ (adoctest-faces "attribute-reference"
+ ;; simple attribute reference
+ "{" adoc-replacement-face "foo" adoc-replacement-face "}"
adoc-replacement-face "\n" nil
+ ;; hyphenated attribute
+ "{" adoc-replacement-face "my-attr" adoc-replacement-face
"}" adoc-replacement-face "\n" nil
+ ;; escaped braces must not hang or get highlighted
+ "\\{not-an-attr\\}" 'no-face "\n" nil))
+
(ert-deftest adoctest-test-block-macro ()
(adoctest-faces "block-macro"
"lorem" adoc-command-face "::" adoc-meta-face "ipsum[]"
adoc-meta-face))