summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--etc/NEWS7
-rw-r--r--lisp/emacs-lisp/rx.el11
-rw-r--r--test/lisp/emacs-lisp/rx-tests.el4
3 files changed, 20 insertions, 2 deletions
diff --git a/etc/NEWS b/etc/NEWS
index f25c3f5dc3d..f955308ebe5 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1336,6 +1336,13 @@ they are now allocated like any other pseudovector. As a result, the
'misc' component, and the 'misc-objects-consed' variable has been
removed.
++++
+** Reversed character ranges are no longer permitted in rx.
+Previously, ranges where the starting character is greater than the
+ending character were silently omitted.
+For example, '(rx (any "@z-a" (?9 . ?0)))' would match '@' only.
+Now, such rx expressions generate an error.
+
* Lisp Changes in Emacs 27.1
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index f6deb45d44e..fdd24317c6a 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -482,7 +482,10 @@ The original order is not preserved. Ranges, \"A-Z\", become pairs, (?A . ?Z)."
(let ((start (funcall decode-char (aref str i)))
(end (funcall decode-char (aref str (+ i 2)))))
(cond ((< start end) (push (cons start end) ret))
- ((= start end) (push start ret)))
+ ((= start end) (push start ret))
+ (t
+ (error "Rx character range `%c-%c' is reversed"
+ start end)))
(setq i (+ i 3))))
(t
;; Single character.
@@ -503,7 +506,10 @@ The original order is not preserved. Ranges, \"A-Z\", become pairs, (?A . ?Z)."
(null (string-match "\\`\\[\\[:[-a-z]+:\\]\\]\\'" translation)))
(error "Invalid char class `%s' in Rx `any'" arg))
(list (substring translation 1 -1)))) ; strip outer brackets
- ((and (integerp (car-safe arg)) (integerp (cdr-safe arg)))
+ ((and (characterp (car-safe arg)) (characterp (cdr-safe arg)))
+ (unless (<= (car arg) (cdr arg))
+ (error "Rx character range `%c-%c' is reversed"
+ (car arg) (cdr arg)))
(list arg))
((stringp arg) (rx-check-any-string arg))
((error
@@ -916,6 +922,7 @@ CHAR
matches any character in SET .... SET may be a character or string.
Ranges of characters can be specified as `A-Z' in strings.
Ranges may also be specified as conses like `(?A . ?Z)'.
+ Reversed ranges like `Z-A' and `(?Z . ?A)' are not permitted.
SET may also be the name of a character class: `digit',
`control', `hex-digit', `blank', `graph', `print', `alnum',
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index 7dd5e3b8de9..4a5919edf02 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -40,6 +40,10 @@
(should (equal (rx (any "\a-\n"))
"[\a-\n]")))
+(ert-deftest rx-char-any-range-bad ()
+ (should-error (rx (any "0-9a-Z")))
+ (should-error (rx (any (?0 . ?9) (?a . ?Z)))))
+
(ert-deftest rx-char-any-raw-byte ()
"Test raw bytes in character alternatives."
;; Separate raw characters.