emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 00f86833ac5: ; perl-mode, cperl-mode: Fix $\" in strings (Bug#696


From: Harald Jörg
Subject: master 00f86833ac5: ; perl-mode, cperl-mode: Fix $\" in strings (Bug#69604)
Date: Thu, 7 Mar 2024 18:43:32 -0500 (EST)

branch: master
commit 00f86833ac5423d57825213ef8b611978be0a3eb
Author: Harald Jörg <haj@posteo.de>
Commit: Harald Jörg <haj@posteo.de>

    ; perl-mode, cperl-mode: Fix $\" in strings (Bug#69604)
    
    * lisp/progmodes/perl-mode.el (perl-syntax-propertize-function):
    Add to syntax-propertize-rules that $ is punctuation in strings.
    
    * lisp/progmodes/cperl-mode.el (cperl-find-pods-heres): capture $\
    to catch the edge case of "$\"".  Make $ a punctuation char in
    strings and comments.
    
    * test/lisp/progmodes/cperl-mode-tests.el (cperl-test-bug-69604):
    New testcases with various combinations of $ " \
---
 lisp/progmodes/cperl-mode.el            | 12 ++++++++++--
 lisp/progmodes/perl-mode.el             | 11 ++++++++++-
 test/lisp/progmodes/cperl-mode-tests.el | 19 +++++++++++++++++++
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 113eed64917..10ac80dffd5 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -4014,7 +4014,10 @@ recursive calls in starting lines of here-documents."
                ;; 1+6+2+1+1+6+1+1+1=20 extra () before this:
                "\\|"
                 ;; -------- backslash-escaped stuff, don't interpret it
-               "\\\\\\(['`\"($]\\)")   ; BACKWACKED something-hairy
+               "\\\\\\(['`\"($]\\)"    ; BACKWACKED something-hairy
+                "\\|"
+                ;; -------- $\ is a variable in code, but not in a string
+                "\\(\\$\\\\\\)")
             "")))
          warning-message)
     (unwind-protect
@@ -4068,7 +4071,12 @@ recursive calls in starting lines of here-documents."
                  (cperl-modify-syntax-type bb cperl-st-punct)))
               ;; No processing in strings/comments beyond this point:
               ((or (nth 3 state) (nth 4 state))
-               t)                      ; Do nothing in comment/string
+                ;; Edge case: In a double-quoted string, $\ is not the
+                ;; punctuation variable, $ must not quote \ here.  We
+                ;; generally make $ a punctuation character in strings
+                ;; and comments (Bug#69604).
+                (when (match-beginning 22)
+                  (cperl-modify-syntax-type (match-beginning 22) 
cperl-st-punct)))
               ((match-beginning 1)     ; POD section
                ;;  "\\(\\`\n?\\|^\n\\)="
                (setq b (match-beginning 0)
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index f74390841fe..f6c4dbed1e2 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -251,7 +251,16 @@
       ;; correctly the \() construct (Bug#11996) as well as references
       ;; to string values.
       ("\\(\\\\\\)['`\"($]" (1 (unless (nth 3 (syntax-ppss))
-                                       (string-to-syntax "."))))
+                                 (string-to-syntax "."))))
+      ;; A "$" in Perl code must escape the next char to protect against
+      ;; misinterpreting Perl's punctuation variables as unbalanced
+      ;; quotes or parens.  This is not needed in strings and broken in
+      ;; the special case of "$\"" (Bug#69604).  Make "$" a punctuation
+      ;; char in strings.
+      ("\\$" (0 (if (save-excursion
+                      (nth 3 (syntax-ppss (match-beginning 0))))
+                    (string-to-syntax ".")
+                  (string-to-syntax "/"))))
       ;; Handle funny names like $DB'stop.
       ("\\$ ?{?\\^?[_[:alpha:]][_[:alnum:]]*\\('\\)[_[:alpha:]]" (1 "_"))
       ;; format statements
diff --git a/test/lisp/progmodes/cperl-mode-tests.el 
b/test/lisp/progmodes/cperl-mode-tests.el
index 62b7fdab7f7..9d9718f719c 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -1431,6 +1431,25 @@ cperl-mode fontifies text after the delimiter as Perl 
code."
     (should (equal (get-text-property (point) 'face)
                    font-lock-comment-face))))
 
+(ert-deftest cperl-test-bug-69604 ()
+  "Verify that $\" in a double-quoted string does not end the string.
+Both `perl-mode' and `cperl-mode' treat ?$ as a quoting/escaping char to
+avoid issues with punctuation variables.  In a string, however, this is
+not appropriate."
+  (let ((strings
+         '("\"$\\\"      in string ---\"; # \"" ; $ must not quote \
+           "$\"     . \" in string ---\"; # \"" ; $ must quote \
+           "\"\\$\" . \" in string ---\"; # \""))) ; \$ must not quote
+    (dolist (string strings)
+      (with-temp-buffer
+        (insert string)
+        (funcall cperl-test-mode)
+        (font-lock-ensure)
+        (goto-char (point-min))
+        (search-forward "in string")
+        (should (equal (get-text-property (point) 'face)
+                       font-lock-string-face))))))
+
 (ert-deftest test-indentation ()
   (ert-test-erts-file (ert-resource-file "cperl-indents.erts")))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]