diff options
| author | Mattias Engdegård | 2020-02-26 14:46:01 +0100 |
|---|---|---|
| committer | Mattias Engdegård | 2020-02-26 22:09:17 +0100 |
| commit | 8d5e8cddab732ac90e9ae930c63f7830f9dab24f (patch) | |
| tree | 6db0e10a351f5d1292a67f4c02c3eefeb00b9714 | |
| parent | 2261f89324997351a41d8f12af513b8ec5e9c26b (diff) | |
| download | emacs-8d5e8cddab732ac90e9ae930c63f7830f9dab24f.tar.gz emacs-8d5e8cddab732ac90e9ae930c63f7830f9dab24f.zip | |
Signal an error for the regexp "[:alnum:]"
Omitting the extra brackets is a common mistake; see discussion at
https://lists.gnu.org/archive/html/emacs-devel/2020-02/msg00215.html
* src/regex-emacs.c (reg_errcode_t, re_error_msgid): Add REG_ECLASSBR.
(regex_compile): Check for the mistake.
* test/src/regex-emacs-tests.el (regexp-invalid): Test.
* etc/NEWS: Announce.
| -rw-r--r-- | etc/NEWS | 5 | ||||
| -rw-r--r-- | src/regex-emacs.c | 21 | ||||
| -rw-r--r-- | test/src/regex-emacs-tests.el | 5 |
3 files changed, 30 insertions, 1 deletions
| @@ -202,6 +202,11 @@ Emacs now supports bignums so this old glitch is no longer needed. | |||
| 202 | 'previous-system-time-locale' have been removed, as they were created | 202 | 'previous-system-time-locale' have been removed, as they were created |
| 203 | by mistake and were not useful to Lisp code. | 203 | by mistake and were not useful to Lisp code. |
| 204 | 204 | ||
| 205 | ** The regexp mistake '[:digit:]' is now an error. | ||
| 206 | The correct syntax is '[[:digit:]]'. Previously, forgetting the extra | ||
| 207 | brackets silently resulted in a regexp that did not at all work as | ||
| 208 | intended. | ||
| 209 | |||
| 205 | 210 | ||
| 206 | * Lisp Changes in Emacs 28.1 | 211 | * Lisp Changes in Emacs 28.1 |
| 207 | 212 | ||
diff --git a/src/regex-emacs.c b/src/regex-emacs.c index 694431c95e2..38824370e05 100644 --- a/src/regex-emacs.c +++ b/src/regex-emacs.c | |||
| @@ -818,7 +818,8 @@ typedef enum | |||
| 818 | REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ | 818 | REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ |
| 819 | REG_ERPAREN, /* Unmatched ) or \); not returned from regcomp. */ | 819 | REG_ERPAREN, /* Unmatched ) or \); not returned from regcomp. */ |
| 820 | REG_ERANGEX, /* Range striding over charsets. */ | 820 | REG_ERANGEX, /* Range striding over charsets. */ |
| 821 | REG_ESIZEBR /* n or m too big in \{n,m\} */ | 821 | REG_ESIZEBR, /* n or m too big in \{n,m\} */ |
| 822 | REG_ECLASSBR, /* Missing [] around [:class:]. */ | ||
| 822 | } reg_errcode_t; | 823 | } reg_errcode_t; |
| 823 | 824 | ||
| 824 | static const char *re_error_msgid[] = | 825 | static const char *re_error_msgid[] = |
| @@ -842,6 +843,7 @@ static const char *re_error_msgid[] = | |||
| 842 | [REG_ERPAREN] = "Unmatched ) or \\)", | 843 | [REG_ERPAREN] = "Unmatched ) or \\)", |
| 843 | [REG_ERANGEX ] = "Range striding over charsets", | 844 | [REG_ERANGEX ] = "Range striding over charsets", |
| 844 | [REG_ESIZEBR ] = "Invalid content of \\{\\}", | 845 | [REG_ESIZEBR ] = "Invalid content of \\{\\}", |
| 846 | [REG_ECLASSBR] = "Class syntax is [[:digit:]]; missing brackets", | ||
| 845 | }; | 847 | }; |
| 846 | 848 | ||
| 847 | /* For 'regs_allocated'. */ | 849 | /* For 'regs_allocated'. */ |
| @@ -2000,6 +2002,23 @@ regex_compile (re_char *pattern, ptrdiff_t size, | |||
| 2000 | 2002 | ||
| 2001 | laststart = b; | 2003 | laststart = b; |
| 2002 | 2004 | ||
| 2005 | /* Check for the mistake of forgetting the extra square brackets, | ||
| 2006 | as in "[:alpha:]". */ | ||
| 2007 | if (*p == ':') | ||
| 2008 | { | ||
| 2009 | re_char *q = p + 1; | ||
| 2010 | while (q != pend && *q != ']') | ||
| 2011 | { | ||
| 2012 | if (*q == ':') | ||
| 2013 | { | ||
| 2014 | if (q + 1 != pend && q[1] == ']' && q > p + 1) | ||
| 2015 | FREE_STACK_RETURN (REG_ECLASSBR); | ||
| 2016 | break; | ||
| 2017 | } | ||
| 2018 | q++; | ||
| 2019 | } | ||
| 2020 | } | ||
| 2021 | |||
| 2003 | /* Test '*p == '^' twice, instead of using an if | 2022 | /* Test '*p == '^' twice, instead of using an if |
| 2004 | statement, so we need only one BUF_PUSH. */ | 2023 | statement, so we need only one BUF_PUSH. */ |
| 2005 | BUF_PUSH (*p == '^' ? charset_not : charset); | 2024 | BUF_PUSH (*p == '^' ? charset_not : charset); |
diff --git a/test/src/regex-emacs-tests.el b/test/src/regex-emacs-tests.el index f9372e37b11..661d416e6a7 100644 --- a/test/src/regex-emacs-tests.el +++ b/test/src/regex-emacs-tests.el | |||
| @@ -803,4 +803,9 @@ This evaluates the TESTS test cases from glibc." | |||
| 803 | (should-not (string-match "å" "\xe5")) | 803 | (should-not (string-match "å" "\xe5")) |
| 804 | (should-not (string-match "[å]" "\xe5"))) | 804 | (should-not (string-match "[å]" "\xe5"))) |
| 805 | 805 | ||
| 806 | (ert-deftest regexp-invalid () | ||
| 807 | ;; relint suppression: Duplicated | ||
| 808 | (should-error (string-match "[:space:]" "") | ||
| 809 | :type 'invalid-regexp)) | ||
| 810 | |||
| 806 | ;;; regex-emacs-tests.el ends here | 811 | ;;; regex-emacs-tests.el ends here |