Subject: Re: bug#53203: Comment with lots of color codes crashes or hangs emacs in scss-mode

From: Lars Ingebrigtsen <[email-masked]>
Date: Sat, 14 May 2022 15:30:26 +0200

But how about just trying to make it stricter?  That is, just allow any
number of selectors, with the separators between.  The following seems
to work fine in the test cases.

diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 1139fd1976..4db3ae82f0 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -944,29 +944,29 @@ css--font-lock-keywords
     ;; I use `keep' this should work better).  But really the part of the
     ;; selector between [...] should simply not be highlighted.
     (,(concat
-       "^[ \t]*\\("
+       "^[ \t]*\\(\\(?:"
        (if (not sassy)
            ;; We don't allow / as first char, so as not to
            ;; take a comment as the beginning of a selector.
-           "[^@/:{}() \t\n][^:{}()]*"
+           "[[:alnum:]%*#.>]+"
          ;; Same as for non-sassy except we do want to allow { and }
          ;; chars in selectors in the case of #{$foo}
          ;; variable interpolation!
          (concat "\\(?:" scss--hash-re
-                 "\\|[^@/:{}() \t\n#]\\)"
-                 "[^:{}()#]*\\(?:" scss--hash-re "[^:{}()#]*\\)*"))
+                 "\\|[[:alnum:]%*#.>]+\\)"))
        ;; Even though pseudo-elements should be prefixed by ::, a
        ;; single colon is accepted for backward compatibility.
        "\\(?:\\(:" (regexp-opt (append css-pseudo-class-ids
                                        css-pseudo-element-ids)
                                t)
-       "\\|::" (regexp-opt css-pseudo-element-ids t) "\\)"
+       "\\|::" (regexp-opt css-pseudo-element-ids t) "\\)\\)?"
+       ;; Braces after selectors.
+       "\\(?:\\[[^]]+\\]\\)?"
+       ;; Parentheses after selectors.
        "\\(?:([^)]+)\\)?"
-       (if (not sassy)
-           "[^:{}()\n]*"
-         (concat "[^:{}()\n#]*\\(?:" scss--hash-re "[^:{}()\n#]*\\)*"))
-       "\\)*"
-       "\\)\\(?:\n[ \t]*\\)*{")
+       ;; Separators between selectors.
+       "[ \t,+~>]*"
+       "\\)+\\)\\(?:\n[ \t]*\\)*{")
      (1 'css-selector keep))
     ;; In the above rule, we allow the open-brace to be on some subsequent
     ;; line.  This will only work if we properly mark the intervening text

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no