diff options
Diffstat (limited to 'gl/m4/regex.m4')
-rw-r--r-- | gl/m4/regex.m4 | 193 |
1 files changed, 158 insertions, 35 deletions
diff --git a/gl/m4/regex.m4 b/gl/m4/regex.m4 index 0945c11a..1c7e562f 100644 --- a/gl/m4/regex.m4 +++ b/gl/m4/regex.m4 | |||
@@ -1,6 +1,6 @@ | |||
1 | # serial 64 | 1 | # serial 73 |
2 | 2 | ||
3 | # Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc. | 3 | # Copyright (C) 1996-2001, 2003-2021 Free Software Foundation, Inc. |
4 | # | 4 | # |
5 | # This file is free software; the Free Software Foundation | 5 | # This file is free software; the Free Software Foundation |
6 | # gives unlimited permission to copy and/or distribute it, | 6 | # gives unlimited permission to copy and/or distribute it, |
@@ -13,6 +13,7 @@ AC_PREREQ([2.50]) | |||
13 | 13 | ||
14 | AC_DEFUN([gl_REGEX], | 14 | AC_DEFUN([gl_REGEX], |
15 | [ | 15 | [ |
16 | AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles | ||
16 | AC_ARG_WITH([included-regex], | 17 | AC_ARG_WITH([included-regex], |
17 | [AS_HELP_STRING([--without-included-regex], | 18 | [AS_HELP_STRING([--without-included-regex], |
18 | [don't compile regex; this is the default on systems | 19 | [don't compile regex; this is the default on systems |
@@ -28,6 +29,7 @@ AC_DEFUN([gl_REGEX], | |||
28 | # If cross compiling, assume the test would fail and use the included | 29 | # If cross compiling, assume the test would fail and use the included |
29 | # regex.c. | 30 | # regex.c. |
30 | AC_CHECK_DECLS_ONCE([alarm]) | 31 | AC_CHECK_DECLS_ONCE([alarm]) |
32 | AC_CHECK_HEADERS_ONCE([malloc.h]) | ||
31 | AC_CACHE_CHECK([for working re_compile_pattern], | 33 | AC_CACHE_CHECK([for working re_compile_pattern], |
32 | [gl_cv_func_re_compile_pattern_working], | 34 | [gl_cv_func_re_compile_pattern_working], |
33 | [AC_RUN_IFELSE( | 35 | [AC_RUN_IFELSE( |
@@ -37,9 +39,19 @@ AC_DEFUN([gl_REGEX], | |||
37 | #include <locale.h> | 39 | #include <locale.h> |
38 | #include <limits.h> | 40 | #include <limits.h> |
39 | #include <string.h> | 41 | #include <string.h> |
40 | #if HAVE_DECL_ALARM | 42 | |
41 | # include <unistd.h> | 43 | #if defined M_CHECK_ACTION || HAVE_DECL_ALARM |
42 | # include <signal.h> | 44 | # include <signal.h> |
45 | # include <unistd.h> | ||
46 | #endif | ||
47 | |||
48 | #if HAVE_MALLOC_H | ||
49 | # include <malloc.h> | ||
50 | #endif | ||
51 | |||
52 | #ifdef M_CHECK_ACTION | ||
53 | /* Exit with distinguishable exit code. */ | ||
54 | static void sigabrt_no_core (int sig) { raise (SIGTERM); } | ||
43 | #endif | 55 | #endif |
44 | ]], | 56 | ]], |
45 | [[int result = 0; | 57 | [[int result = 0; |
@@ -49,15 +61,22 @@ AC_DEFUN([gl_REGEX], | |||
49 | const char *s; | 61 | const char *s; |
50 | struct re_registers regs; | 62 | struct re_registers regs; |
51 | 63 | ||
64 | /* Some builds of glibc go into an infinite loop on this | ||
65 | test. Use alarm to force death, and mallopt to avoid | ||
66 | malloc recursion in diagnosing the corrupted heap. */ | ||
52 | #if HAVE_DECL_ALARM | 67 | #if HAVE_DECL_ALARM |
53 | /* Some builds of glibc go into an infinite loop on this test. */ | ||
54 | signal (SIGALRM, SIG_DFL); | 68 | signal (SIGALRM, SIG_DFL); |
55 | alarm (2); | 69 | alarm (2); |
56 | #endif | 70 | #endif |
71 | #ifdef M_CHECK_ACTION | ||
72 | signal (SIGABRT, sigabrt_no_core); | ||
73 | mallopt (M_CHECK_ACTION, 2); | ||
74 | #endif | ||
75 | |||
57 | if (setlocale (LC_ALL, "en_US.UTF-8")) | 76 | if (setlocale (LC_ALL, "en_US.UTF-8")) |
58 | { | 77 | { |
59 | { | 78 | { |
60 | /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html | 79 | /* https://sourceware.org/ml/libc-hacker/2006-09/msg00008.html |
61 | This test needs valgrind to catch the bug on Debian | 80 | This test needs valgrind to catch the bug on Debian |
62 | GNU/Linux 3.1 x86, but it might catch the bug better | 81 | GNU/Linux 3.1 x86, but it might catch the bug better |
63 | on other platforms and it shouldn't hurt to try the | 82 | on other platforms and it shouldn't hurt to try the |
@@ -71,16 +90,20 @@ AC_DEFUN([gl_REGEX], | |||
71 | s = re_compile_pattern (pat, sizeof pat - 1, ®ex); | 90 | s = re_compile_pattern (pat, sizeof pat - 1, ®ex); |
72 | if (s) | 91 | if (s) |
73 | result |= 1; | 92 | result |= 1; |
74 | else if (re_search (®ex, data, sizeof data - 1, | 93 | else |
75 | 0, sizeof data - 1, ®s) | 94 | { |
76 | != -1) | 95 | if (re_search (®ex, data, sizeof data - 1, |
77 | result |= 1; | 96 | 0, sizeof data - 1, ®s) |
97 | != -1) | ||
98 | result |= 1; | ||
99 | regfree (®ex); | ||
100 | } | ||
78 | } | 101 | } |
79 | 102 | ||
80 | { | 103 | { |
81 | /* This test is from glibc bug 15078. | 104 | /* This test is from glibc bug 15078. |
82 | The test case is from Andreas Schwab in | 105 | The test case is from Andreas Schwab in |
83 | <http://www.sourceware.org/ml/libc-alpha/2013-01/msg00967.html>. | 106 | <https://sourceware.org/ml/libc-alpha/2013-01/msg00967.html>. |
84 | */ | 107 | */ |
85 | static char const pat[] = "[^x]x"; | 108 | static char const pat[] = "[^x]x"; |
86 | static char const data[] = | 109 | static char const data[] = |
@@ -105,6 +128,7 @@ AC_DEFUN([gl_REGEX], | |||
105 | 0, sizeof data - 1, 0); | 128 | 0, sizeof data - 1, 0); |
106 | if (i != 0 && i != 21) | 129 | if (i != 0 && i != 21) |
107 | result |= 1; | 130 | result |= 1; |
131 | regfree (®ex); | ||
108 | } | 132 | } |
109 | } | 133 | } |
110 | 134 | ||
@@ -118,9 +142,13 @@ AC_DEFUN([gl_REGEX], | |||
118 | s = re_compile_pattern ("a[^x]b", 6, ®ex); | 142 | s = re_compile_pattern ("a[^x]b", 6, ®ex); |
119 | if (s) | 143 | if (s) |
120 | result |= 2; | 144 | result |= 2; |
121 | /* This should fail, but succeeds for glibc-2.5. */ | 145 | else |
122 | else if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) | 146 | { |
123 | result |= 2; | 147 | /* This should fail, but succeeds for glibc-2.5. */ |
148 | if (re_search (®ex, "a\nb", 3, 0, 3, ®s) != -1) | ||
149 | result |= 2; | ||
150 | regfree (®ex); | ||
151 | } | ||
124 | 152 | ||
125 | /* This regular expression is from Spencer ere test number 75 | 153 | /* This regular expression is from Spencer ere test number 75 |
126 | in grep-2.3. */ | 154 | in grep-2.3. */ |
@@ -132,7 +160,10 @@ AC_DEFUN([gl_REGEX], | |||
132 | s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); | 160 | s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, ®ex); |
133 | /* This should fail with _Invalid character class name_ error. */ | 161 | /* This should fail with _Invalid character class name_ error. */ |
134 | if (!s) | 162 | if (!s) |
135 | result |= 4; | 163 | { |
164 | result |= 4; | ||
165 | regfree (®ex); | ||
166 | } | ||
136 | 167 | ||
137 | /* Ensure that [b-a] is diagnosed as invalid, when | 168 | /* Ensure that [b-a] is diagnosed as invalid, when |
138 | using RE_NO_EMPTY_RANGES. */ | 169 | using RE_NO_EMPTY_RANGES. */ |
@@ -140,13 +171,18 @@ AC_DEFUN([gl_REGEX], | |||
140 | memset (®ex, 0, sizeof regex); | 171 | memset (®ex, 0, sizeof regex); |
141 | s = re_compile_pattern ("a[b-a]", 6, ®ex); | 172 | s = re_compile_pattern ("a[b-a]", 6, ®ex); |
142 | if (s == 0) | 173 | if (s == 0) |
143 | result |= 8; | 174 | { |
175 | result |= 8; | ||
176 | regfree (®ex); | ||
177 | } | ||
144 | 178 | ||
145 | /* This should succeed, but does not for glibc-2.1.3. */ | 179 | /* This should succeed, but does not for glibc-2.1.3. */ |
146 | memset (®ex, 0, sizeof regex); | 180 | memset (®ex, 0, sizeof regex); |
147 | s = re_compile_pattern ("{1", 2, ®ex); | 181 | s = re_compile_pattern ("{1", 2, ®ex); |
148 | if (s) | 182 | if (s) |
149 | result |= 8; | 183 | result |= 8; |
184 | else | ||
185 | regfree (®ex); | ||
150 | 186 | ||
151 | /* The following example is derived from a problem report | 187 | /* The following example is derived from a problem report |
152 | against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */ | 188 | against gawk from Jorge Stolfi <stolfi@ic.unicamp.br>. */ |
@@ -154,17 +190,35 @@ AC_DEFUN([gl_REGEX], | |||
154 | s = re_compile_pattern ("[an\371]*n", 7, ®ex); | 190 | s = re_compile_pattern ("[an\371]*n", 7, ®ex); |
155 | if (s) | 191 | if (s) |
156 | result |= 8; | 192 | result |= 8; |
157 | /* This should match, but does not for glibc-2.2.1. */ | 193 | else |
158 | else if (re_match (®ex, "an", 2, 0, ®s) != 2) | 194 | { |
159 | result |= 8; | 195 | /* This should match, but does not for glibc-2.2.1. */ |
196 | if (re_match (®ex, "an", 2, 0, ®s) != 2) | ||
197 | result |= 8; | ||
198 | else | ||
199 | { | ||
200 | free (regs.start); | ||
201 | free (regs.end); | ||
202 | } | ||
203 | regfree (®ex); | ||
204 | } | ||
160 | 205 | ||
161 | memset (®ex, 0, sizeof regex); | 206 | memset (®ex, 0, sizeof regex); |
162 | s = re_compile_pattern ("x", 1, ®ex); | 207 | s = re_compile_pattern ("x", 1, ®ex); |
163 | if (s) | 208 | if (s) |
164 | result |= 8; | 209 | result |= 8; |
165 | /* glibc-2.2.93 does not work with a negative RANGE argument. */ | 210 | else |
166 | else if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) | 211 | { |
167 | result |= 8; | 212 | /* glibc-2.2.93 does not work with a negative RANGE argument. */ |
213 | if (re_search (®ex, "wxy", 3, 2, -2, ®s) != 1) | ||
214 | result |= 8; | ||
215 | else | ||
216 | { | ||
217 | free (regs.start); | ||
218 | free (regs.end); | ||
219 | } | ||
220 | regfree (®ex); | ||
221 | } | ||
168 | 222 | ||
169 | /* The version of regex.c in older versions of gnulib | 223 | /* The version of regex.c in older versions of gnulib |
170 | ignored RE_ICASE. Detect that problem too. */ | 224 | ignored RE_ICASE. Detect that problem too. */ |
@@ -173,25 +227,89 @@ AC_DEFUN([gl_REGEX], | |||
173 | s = re_compile_pattern ("x", 1, ®ex); | 227 | s = re_compile_pattern ("x", 1, ®ex); |
174 | if (s) | 228 | if (s) |
175 | result |= 16; | 229 | result |= 16; |
176 | else if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) | 230 | else |
177 | result |= 16; | 231 | { |
232 | if (re_search (®ex, "WXY", 3, 0, 3, ®s) < 0) | ||
233 | result |= 16; | ||
234 | else | ||
235 | { | ||
236 | free (regs.start); | ||
237 | free (regs.end); | ||
238 | } | ||
239 | regfree (®ex); | ||
240 | } | ||
178 | 241 | ||
179 | /* Catch a bug reported by Vin Shelton in | 242 | /* Catch a bug reported by Vin Shelton in |
180 | http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html | 243 | https://lists.gnu.org/r/bug-coreutils/2007-06/msg00089.html |
181 | */ | 244 | */ |
182 | re_set_syntax (RE_SYNTAX_POSIX_BASIC | 245 | re_set_syntax (RE_SYNTAX_POSIX_BASIC |
183 | & ~RE_CONTEXT_INVALID_DUP | 246 | & ~RE_CONTEXT_INVALID_DUP |
184 | & ~RE_NO_EMPTY_RANGES); | 247 | & ~RE_NO_EMPTY_RANGES); |
185 | memset (®ex, 0, sizeof regex); | 248 | memset (®ex, 0, sizeof regex); |
186 | s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, ®ex); | 249 | s = re_compile_pattern ("[[:alnum:]_-]\\\\+\$", 16, ®ex); |
187 | if (s) | 250 | if (s) |
188 | result |= 32; | 251 | result |= 32; |
252 | else | ||
253 | regfree (®ex); | ||
189 | 254 | ||
190 | /* REG_STARTEND was added to glibc on 2004-01-15. | 255 | /* REG_STARTEND was added to glibc on 2004-01-15. |
191 | Reject older versions. */ | 256 | Reject older versions. */ |
192 | if (! REG_STARTEND) | 257 | if (! REG_STARTEND) |
193 | result |= 64; | 258 | result |= 64; |
194 | 259 | ||
260 | /* Matching with the compiled form of this regexp would provoke | ||
261 | an assertion failure prior to glibc-2.28: | ||
262 | regexec.c:1375: pop_fail_stack: Assertion 'num >= 0' failed | ||
263 | With glibc-2.28, compilation fails and reports the invalid | ||
264 | back reference. */ | ||
265 | re_set_syntax (RE_SYNTAX_POSIX_EGREP); | ||
266 | memset (®ex, 0, sizeof regex); | ||
267 | s = re_compile_pattern ("0|()0|\\\\1|0", 10, ®ex); | ||
268 | if (!s) | ||
269 | { | ||
270 | memset (®s, 0, sizeof regs); | ||
271 | i = re_search (®ex, "x", 1, 0, 1, ®s); | ||
272 | if (i != -1) | ||
273 | result |= 64; | ||
274 | if (0 <= i) | ||
275 | { | ||
276 | free (regs.start); | ||
277 | free (regs.end); | ||
278 | } | ||
279 | regfree (®ex); | ||
280 | } | ||
281 | else | ||
282 | { | ||
283 | if (strcmp (s, "Invalid back reference")) | ||
284 | result |= 64; | ||
285 | } | ||
286 | |||
287 | /* glibc bug 11053. */ | ||
288 | re_set_syntax (RE_SYNTAX_POSIX_BASIC); | ||
289 | memset (®ex, 0, sizeof regex); | ||
290 | static char const pat_sub2[] = "\\\\(a*\\\\)*a*\\\\1"; | ||
291 | s = re_compile_pattern (pat_sub2, sizeof pat_sub2 - 1, ®ex); | ||
292 | if (s) | ||
293 | result |= 64; | ||
294 | else | ||
295 | { | ||
296 | memset (®s, 0, sizeof regs); | ||
297 | static char const data[] = "a"; | ||
298 | int datalen = sizeof data - 1; | ||
299 | i = re_search (®ex, data, datalen, 0, datalen, ®s); | ||
300 | if (i != 0) | ||
301 | result |= 64; | ||
302 | else if (regs.num_regs < 2) | ||
303 | result |= 64; | ||
304 | else if (! (regs.start[0] == 0 && regs.end[0] == 1)) | ||
305 | result |= 64; | ||
306 | else if (! (regs.start[1] == 0 && regs.end[1] == 0)) | ||
307 | result |= 64; | ||
308 | regfree (®ex); | ||
309 | free (regs.start); | ||
310 | free (regs.end); | ||
311 | } | ||
312 | |||
195 | #if 0 | 313 | #if 0 |
196 | /* It would be nice to reject hosts whose regoff_t values are too | 314 | /* It would be nice to reject hosts whose regoff_t values are too |
197 | narrow (including glibc on hosts with 64-bit ptrdiff_t and | 315 | narrow (including glibc on hosts with 64-bit ptrdiff_t and |
@@ -206,13 +324,19 @@ AC_DEFUN([gl_REGEX], | |||
206 | 324 | ||
207 | return result; | 325 | return result; |
208 | ]])], | 326 | ]])], |
209 | [gl_cv_func_re_compile_pattern_working=yes], | 327 | [gl_cv_func_re_compile_pattern_working=yes], |
210 | [gl_cv_func_re_compile_pattern_working=no], | 328 | [gl_cv_func_re_compile_pattern_working=no], |
211 | dnl When crosscompiling, assume it is not working. | 329 | [case "$host_os" in |
212 | [gl_cv_func_re_compile_pattern_working=no])]) | 330 | # Guess no on native Windows. |
213 | case $gl_cv_func_re_compile_pattern_working in #( | 331 | mingw*) gl_cv_func_re_compile_pattern_working="guessing no" ;; |
214 | yes) ac_use_included_regex=no;; #( | 332 | # Otherwise obey --enable-cross-guesses. |
215 | no) ac_use_included_regex=yes;; | 333 | *) gl_cv_func_re_compile_pattern_working="$gl_cross_guess_normal" ;; |
334 | esac | ||
335 | ]) | ||
336 | ]) | ||
337 | case "$gl_cv_func_re_compile_pattern_working" in #( | ||
338 | *yes) ac_use_included_regex=no;; #( | ||
339 | *no) ac_use_included_regex=yes;; | ||
216 | esac | 340 | esac |
217 | ;; | 341 | ;; |
218 | *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) | 342 | *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex]) |
@@ -266,8 +390,7 @@ AC_DEFUN([gl_PREREQ_REGEX], | |||
266 | AC_REQUIRE([AC_C_RESTRICT]) | 390 | AC_REQUIRE([AC_C_RESTRICT]) |
267 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) | 391 | AC_REQUIRE([AC_TYPE_MBSTATE_T]) |
268 | AC_REQUIRE([gl_EEMALLOC]) | 392 | AC_REQUIRE([gl_EEMALLOC]) |
269 | AC_REQUIRE([gl_GLIBC21]) | ||
270 | AC_CHECK_HEADERS([libintl.h]) | 393 | AC_CHECK_HEADERS([libintl.h]) |
271 | AC_CHECK_FUNCS_ONCE([isblank iswctype wcscoll]) | 394 | AC_CHECK_FUNCS_ONCE([isblank iswctype]) |
272 | AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]]) | 395 | AC_CHECK_DECLS([isblank], [], [], [[#include <ctype.h>]]) |
273 | ]) | 396 | ]) |