[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/relint 41fad874a3 1/2: Find more bad string escapes: \8
From: |
Mattias Engdegård |
Subject: |
[elpa] externals/relint 41fad874a3 1/2: Find more bad string escapes: \8, \9, \x without following hex digit |
Date: |
Fri, 24 Mar 2023 08:27:13 -0400 (EDT) |
branch: externals/relint
commit 41fad874a3968d5ae36fada9e4e4991f3f6ef39a
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>
Find more bad string escapes: \8, \9, \x without following hex digit
"\x" is particularly pernicious since it unexpectedly yields a NUL;
this bug has been in Emacs for a very long time.
---
README | 51 +++++++++++++++++++++++++++++----------------------
relint.el | 14 +++++++++-----
test/13.elisp | 4 ++++
test/13.expected | 4 ++++
4 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/README b/README
index 80500adc87..1db153a450 100644
--- a/README
+++ b/README
@@ -227,28 +227,6 @@ skip-syntax-forward and skip-syntax-backward.
In general, A?, where A matches the empty string, can be
simplified to just A.
- - Ineffective string escape '\X'
-
- A backslash precedes a character that does not need escaping in a
- string literal (any string, not just regexps), like in "hot\-dog".
-
- If the backslash should be part of the string then it probably
- needs to be doubled; otherwise, it is pointless and should be
- removed to avoid confusion.
-
- In Emacs versions older than 27.1, a left round or square bracket,
- '(' or '[', at the very start of a line in a multi-line string
- could sometimes fool the Emacs-Lisp mode into believing it to be
- the start of a function, thus people sometimes precede such
- brackets with an otherwise unnecessary backslash. However, there
- is usually no reason to put backslashes before brackets in strings
- in general.
-
- - Suspect range '+-X' or 'X-+'
-
- A character range with '+' as one of its endpoints is more often an
- incorrect attempt to include both '+' and '-' in the set.
-
- Unnecessarily escaped 'X'
A character is backslash-escaped in a skip set despite not being
@@ -324,6 +302,35 @@ skip-syntax-forward and skip-syntax-backward.
A string argument to skip-syntax-forward or skip-syntax-backward
is empty or "^", neither of which makes sense.
+ - Ineffective string escape '\X'
+
+ A backslash precedes a character that does not need escaping in a
+ string literal (any string, not just regexps), like in "hot\-dog".
+
+ If the backslash should be part of the string then it probably
+ needs to be doubled; otherwise, it is pointless and should be
+ removed to avoid confusion.
+
+ In Emacs versions older than 27.1, a left round or square bracket,
+ '(' or '[', at the very start of a line in a multi-line string
+ could sometimes fool the Emacs-Lisp mode into believing it to be
+ the start of a function, thus people sometimes precede such
+ brackets with an otherwise unnecessary backslash. However, there
+ is usually no reason to put backslashes before brackets in strings
+ in general.
+
+ - Character escape '\x' not followed by hex digit
+
+ In Emacs versions older than 30.1, a hex escape without any actual
+ hex digits, as in "\x", was silently accepted as a null byte which
+ is not what anyone would expect. If the backslash should be
+ included in the string, double it as usual.
+
+ - Suspect range '+-X' or 'X-+'
+
+ A character range with '+' as one of its endpoints is more often an
+ incorrect attempt to include both '+' and '-' in the set.
+
* Suppressing diagnostics
diff --git a/relint.el b/relint.el
index fe27c17ba8..51a02aa6ef 100644
--- a/relint.el
+++ b/relint.el
@@ -2303,9 +2303,12 @@ STRING-START is the start of the string literal (first
double quote)."
(and (memq c '(?\( ?\) ?\[ ?\] ?\'))
(relint--in-doc-string-p string-start)))
(relint--warn (point) nil
- (format-message
- "Ineffective string escape `\\%s'"
- (relint--escape-string (char-to-string c) nil))))))
+ (if (eq c ?x)
+ (format-message
+ "Character escape `\\x' not followed by hex digit")
+ (format-message
+ "Ineffective string escape `\\%s'"
+ (relint--escape-string (char-to-string c) nil)))))))
(defun relint--check-for-misplaced-backslashes ()
"Check for misplaced backslashes in the current buffer."
@@ -2322,10 +2325,11 @@ STRING-START is the start of the string literal (first
double quote)."
(forward-char)
(while (not (memq (char-after) '(?\" nil)))
(when (looking-at
- (rx (1+ (or (seq ?\\ (any "0-9" "xuUN" "abfnrtv"
+ (rx (1+ (or (seq ?\\ (or (any "0-7" "uUN" "abfnrtv"
"des" "^" " "
?\\ ?\n ?\"
- "CM"))
+ "CM")
+ (seq "x" xdigit)))
(not (any ?\\ ?\"))))))
(goto-char (match-end 0)))
(when (eq (following-char) ?\\)
diff --git a/test/13.elisp b/test/13.elisp
index 1f8cb5826f..d07f72fbd2 100644
--- a/test/13.elisp
+++ b/test/13.elisp
@@ -17,3 +17,7 @@ and \a \b \f \n \r \t \v \d \e \s \^P"))
(defun f2 ()
(re-search-forward "\$\.x\+\+")
'("bracketed \q string"))
+
+(defun f3 ()
+ (print "a \7 \8 \9 b")
+ (print "c \xf \xg \x d"))
diff --git a/test/13.expected b/test/13.expected
index 53a4568aab..1bf32daa53 100644
--- a/test/13.expected
+++ b/test/13.expected
@@ -26,3 +26,7 @@
....^
13.elisp:18:30: Ineffective string escape `\+'
13.elisp:19:16: Ineffective string escape `\q'
+13.elisp:22:16: Ineffective string escape `\8'
+13.elisp:22:19: Ineffective string escape `\9'
+13.elisp:23:17: Character escape `\x' not followed by hex digit
+13.elisp:23:21: Character escape `\x' not followed by hex digit