diff options
| author | Mattias EngdegÄrd | 2023-06-20 12:12:50 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2023-06-21 18:00:26 +0200 |
| commit | be91192ecb1e0dff794582cd463f0a6480d160ef (patch) | |
| tree | 156031723d39088ce4e2dd52a3a7b7068fbc5880 /test/src | |
| parent | dae8aab52874441a70a94435d50f25b27301d9b0 (diff) | |
| download | emacs-be91192ecb1e0dff794582cd463f0a6480d160ef.tar.gz emacs-be91192ecb1e0dff794582cd463f0a6480d160ef.zip | |
Straighten regexp postfix operator after zero-width assertion parse
The zero-width assertions \` \' \b \B were parsed in a sloppy way so
that a following postfix repetition operator could yield surprising
results. For instance, "\\b*" would act as "\\b\\*", and "xy\\b*"
would act as "\\(?:xy\\b\\)*".
Except for \` and ^, any following postfix operator now applies to the
zero-width assertion itself only, which is predictable and consistent
with other assertions, if useless in practice.
For historical compatibility, an operator character following \` and ^
always becomes a literal. (Bug#64128)
* src/regex-emacs.c (regex_compile):
Set `laststart` appropriately for each zero-width assertion instead
of leaving it with whatever value it had before.
Remove a redundant condition.
* test/src/regex-emacs-tests.el
(regexp-tests-zero-width-assertion-repetition): New test.
* doc/lispref/searching.texi (Regexp Special):
Say that repetition operators are not special after \`,
and that they work as expected after other backslash escapes.
* etc/NEWS: Announce.
Diffstat (limited to 'test/src')
| -rw-r--r-- | test/src/regex-emacs-tests.el | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/test/src/regex-emacs-tests.el b/test/src/regex-emacs-tests.el index 52d43775b8e..08a93dbf30e 100644 --- a/test/src/regex-emacs-tests.el +++ b/test/src/regex-emacs-tests.el | |||
| @@ -883,4 +883,70 @@ This evaluates the TESTS test cases from glibc." | |||
| 883 | (should (looking-at "x*\\(=\\|:\\)*")) | 883 | (should (looking-at "x*\\(=\\|:\\)*")) |
| 884 | (should (looking-at "x*=*?")))) | 884 | (should (looking-at "x*=*?")))) |
| 885 | 885 | ||
| 886 | (ert-deftest regexp-tests-zero-width-assertion-repetition () | ||
| 887 | ;; Check compatibility behaviour with repetition operators after | ||
| 888 | ;; certain zero-width assertions (bug#64128). | ||
| 889 | |||
| 890 | ;; This function is just to hide ugly regexps from relint so that it | ||
| 891 | ;; doesn't complain about them. | ||
| 892 | (cl-flet ((smatch (re str) (string-match re str))) | ||
| 893 | ;; Postfix operators after ^ and \` become literals, for historical | ||
| 894 | ;; compatibility. Only the first character of a lazy operator (like *?) | ||
| 895 | ;; becomes a literal. | ||
| 896 | (should (equal (smatch "^*a" "x\n*a") 2)) | ||
| 897 | (should (equal (smatch "^*?a" "x\n*a") 2)) | ||
| 898 | (should (equal (smatch "^*?a" "x\na") 2)) | ||
| 899 | (should (equal (smatch "^*?a" "x\n**a") nil)) | ||
| 900 | |||
| 901 | (should (equal (smatch "\\`*a" "*a") 0)) | ||
| 902 | (should (equal (smatch "\\`*?a" "*a") 0)) | ||
| 903 | (should (equal (smatch "\\`*?a" "a") 0)) | ||
| 904 | (should (equal (smatch "\\`*?a" "**a") nil)) | ||
| 905 | |||
| 906 | ;; Other zero-width assertions are treated as normal elements, so postfix | ||
| 907 | ;; operators apply to them alone (which is pointless but valid). | ||
| 908 | (should (equal (smatch "\\b*!" "*!") 1)) | ||
| 909 | (should (equal (smatch "!\\b+;" "!;") nil)) | ||
| 910 | (should (equal (smatch "!\\b+a" "!a") 0)) | ||
| 911 | |||
| 912 | (should (equal (smatch "\\B*!" "*!") 1)) | ||
| 913 | (should (equal (smatch "!\\B+;" "!;") 0)) | ||
| 914 | (should (equal (smatch "!\\B+a" "!a") nil)) | ||
| 915 | |||
| 916 | (should (equal (smatch "\\<*b" "*b") 1)) | ||
| 917 | (should (equal (smatch "a\\<*b" "ab") 0)) | ||
| 918 | (should (equal (smatch ";\\<*b" ";b") 0)) | ||
| 919 | (should (equal (smatch "a\\<+b" "ab") nil)) | ||
| 920 | (should (equal (smatch ";\\<+b" ";b") 0)) | ||
| 921 | |||
| 922 | (should (equal (smatch "\\>*;" "*;") 1)) | ||
| 923 | (should (equal (smatch "a\\>*b" "ab") 0)) | ||
| 924 | (should (equal (smatch "a\\>*;" "a;") 0)) | ||
| 925 | (should (equal (smatch "a\\>+b" "ab") nil)) | ||
| 926 | (should (equal (smatch "a\\>+;" "a;") 0)) | ||
| 927 | |||
| 928 | (should (equal (smatch "a\\'" "ab") nil)) | ||
| 929 | (should (equal (smatch "b\\'" "ab") 1)) | ||
| 930 | (should (equal (smatch "a\\'*b" "ab") 0)) | ||
| 931 | (should (equal (smatch "a\\'+" "ab") nil)) | ||
| 932 | (should (equal (smatch "b\\'+" "ab") 1)) | ||
| 933 | (should (equal (smatch "\\'+" "+") 1)) | ||
| 934 | |||
| 935 | (should (equal (smatch "\\_<*b" "*b") 1)) | ||
| 936 | (should (equal (smatch "a\\_<*b" "ab") 0)) | ||
| 937 | (should (equal (smatch " \\_<*b" " b") 0)) | ||
| 938 | (should (equal (smatch "a\\_<+b" "ab") nil)) | ||
| 939 | (should (equal (smatch " \\_<+b" " b") 0)) | ||
| 940 | |||
| 941 | (should (equal (smatch "\\_>*;" "*;") 1)) | ||
| 942 | (should (equal (smatch "a\\_>*b" "ab") 0)) | ||
| 943 | (should (equal (smatch "a\\_>* " "a ") 0)) | ||
| 944 | (should (equal (smatch "a\\_>+b" "ab") nil)) | ||
| 945 | (should (equal (smatch "a\\_>+ " "a ") 0)) | ||
| 946 | |||
| 947 | (should (equal (smatch "\\=*b" "*b") 1)) | ||
| 948 | (should (equal (smatch "a\\=*b" "a*b") nil)) | ||
| 949 | (should (equal (smatch "a\\=*b" "ab") 0)) | ||
| 950 | )) | ||
| 951 | |||
| 886 | ;;; regex-emacs-tests.el ends here | 952 | ;;; regex-emacs-tests.el ends here |