emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 3ed1621: Disallow reversed char ranges in `rx'


From: Mattias Engdegård
Subject: [Emacs-diffs] master 3ed1621: Disallow reversed char ranges in `rx'
Date: Tue, 19 Mar 2019 15:31:39 -0400 (EDT)

branch: master
commit 3ed1621d843e057ad879fbed3605d32f55a065b9
Author: Mattias Engdegård <address@hidden>
Commit: Mattias Engdegård <address@hidden>

    Disallow reversed char ranges in `rx'
    
    (any "a-Z0-9") generated "[0-9]", and (any (?9 . ?0)) generated "[9-0]".
    Reversed ranges are either mistakes or abuse.  Neither should be allowed.
    
    etc/NEWS: Explain the change.
    lisp/emacs-lisp/rx.el (rx): Document.
    (rx-check-any-string, rx-check-any): Add error checks for reversed ranges.
    test/lisp/emacs-lisp/rx-tests.el (rx-char-any-range-bad): New test.
---
 etc/NEWS                         |  7 +++++++
 lisp/emacs-lisp/rx.el            | 11 +++++++++--
 test/lisp/emacs-lisp/rx-tests.el |  4 ++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index f25c3f5..f955308 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 f6deb45..fdd2431 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 7dd5e3b..4a5919e 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.



reply via email to

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