aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-12-20 09:47:44 -0200
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2018-07-04 09:54:45 -0300
commiteb04c21373e2a2885f3d52ff192b0499afe3c672 (patch)
tree040d92dd6f342295f296df31de00ed9ace1b7d67
parentb11643c21c5c9d67a69c8ae952e5231ce002e7f1 (diff)
downloadglibc-eb04c21373e2a2885f3d52ff192b0499afe3c672.tar.xz
glibc-eb04c21373e2a2885f3d52ff192b0499afe3c672.zip
posix: Sync gnulib regex implementation
This patch syncs the regex implementation with gnulib (commit 0ee5212). Only two changes in GLIBC regex testing are required: 1. posix/bug-regex28.c: as previously discussed [1] the change of expected results on the pattern should be safe. 2. posix/PCRE.tests: the ERE (a)|\1 is malformed (in the sense that the \1 doesn't mean anything) and although current GLIBC accepts it has undefined behavior. This patch removes the specific test. This sync contains some patches from thread 'Regex: Make libc regex more usable outside GLIBC.' [2] which have been pushed upstream in gnulib. This patches also fixes some regex issues (BZ #23233, BZ #21163, BZ #18986, BZ #13762) and I did not add testcases for both #23233 and #13762 because I couldn't think a simple way to trigger the expected failure path to trigger them. Checked on x86_64-linux-gnu and i686-linux-gnu. [BZ #23233] [BZ #21163] [BZ #18986] [BZ #13762] * posix/Makefile (tests): Add bug-regex37 and bug-regex38. * posix/PCRE.tests: Remove invalid test. * posix/bug-regex28.c: Fix expected values for used syntax. * posix/bug-regex37.c: New file. * posix/bug-regex38.c: Likewise. * posix/regcomp.c: Sync with gnulib. * posix/regex.c: Likewise. * posix/regex.h: Likewise. * posix/regex_internal.c: Likewise. * posix/regex_internal.h: Likewise. * posix/regexec.c: Likewise. [1] https://sourceware.org/ml/libc-alpha/2017-12/msg00807.html [2] https://sourceware.org/ml/libc-alpha/2017-12/msg00237.html
-rw-r--r--ChangeLog18
-rw-r--r--posix/Makefile3
-rw-r--r--posix/PCRE.tests13
-rw-r--r--posix/bug-regex28.c46
-rw-r--r--posix/bug-regex37.c32
-rw-r--r--posix/bug-regex38.c32
-rw-r--r--posix/regcomp.c597
-rw-r--r--posix/regex.c21
-rw-r--r--posix/regex.h335
-rw-r--r--posix/regex_internal.c295
-rw-r--r--posix/regex_internal.h442
-rw-r--r--posix/regexec.c936
12 files changed, 1609 insertions, 1161 deletions
diff --git a/ChangeLog b/ChangeLog
index 90dfb66d8e..c17caff776 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2018-07-04 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+
+ [BZ #23233]
+ [BZ #21163]
+ [BZ #18986]
+ [BZ #13762]
+ * posix/Makefile (tests): Add bug-regex37 and bug-regex38.
+ * posix/PCRE.tests: Remove invalid test.
+ * posix/bug-regex28.c: Fix expected values for used syntax.
+ * posix/bug-regex37.c: New file.
+ * posix/bug-regex38.c: Likewise.
+ * posix/regcomp.c: Sync with gnulib.
+ * posix/regex.c: Likewise.
+ * posix/regex.h: Likewise.
+ * posix/regex_internal.c: Likewise.
+ * posix/regex_internal.h: Likewise.
+ * posix/regexec.c: Likewise.
+
2018-06-26 Mike FABIAN <mfabian@redhat.com>
[BZ #23308]
diff --git a/posix/Makefile b/posix/Makefile
index 989e42e1f8..00c62841a2 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -95,7 +95,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \
tst-posix_spawn-fd tst-posix_spawn-setsid \
tst-posix_fadvise tst-posix_fadvise64 \
tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \
- tst-glob-tilde test-ssize-max tst-spawn4
+ tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \
+ bug-regex38
tests-internal := bug-regex5 bug-regex20 bug-regex33 \
tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \
tst-glob_lstat_compat tst-spawn4-compat
diff --git a/posix/PCRE.tests b/posix/PCRE.tests
index 0fb9cadafc..da63b86637 100644
--- a/posix/PCRE.tests
+++ b/posix/PCRE.tests
@@ -1774,19 +1774,6 @@ No match
0: abcabc
1: abc
-/(a)|\1/
- a
- 0: a
- 1: a
- *** Failers
- 0: a
- 1: a
- ab
- 0: a
- 1: a
- x
-No match
-
/abc/i
ABC
0: ABC
diff --git a/posix/bug-regex28.c b/posix/bug-regex28.c
index 5353edf373..ba263b27c8 100644
--- a/posix/bug-regex28.c
+++ b/posix/bug-regex28.c
@@ -21,18 +21,22 @@
#include <stdio.h>
#include <string.h>
+#include <support/test-driver.h>
+#include <support/check.h>
+
struct tests
{
const char *regex;
const char *string;
reg_syntax_t syntax;
int retval;
-} tests[] = {
+};
+static const struct tests tests[] = {
#define EGREP RE_SYNTAX_EGREP
#define EGREP_NL (RE_SYNTAX_EGREP | RE_DOT_NEWLINE) & ~RE_HAT_LISTS_NOT_NEWLINE
- { "a.b", "a\nb", EGREP, -1 },
+ { "a.b", "a\nb", EGREP, 0 },
{ "a.b", "a\nb", EGREP_NL, 0 },
- { "a[^x]b", "a\nb", EGREP, -1 },
+ { "a[^x]b", "a\nb", EGREP, 0 },
{ "a[^x]b", "a\nb", EGREP_NL, 0 },
/* While \S and \W are internally handled as [^[:space:]] and [^[:alnum:]_],
RE_HAT_LISTS_NOT_NEWLINE did not make any difference, so ensure
@@ -42,33 +46,33 @@ struct tests
{ "a\\Wb", "a\nb", EGREP, 0 },
{ "a\\Wb", "a\nb", EGREP_NL, 0 }
};
+static const size_t tests_size = sizeof (tests) / sizeof (tests[0]);
-int
-main (void)
+static int
+do_test (void)
{
struct re_pattern_buffer r;
- size_t i;
- int ret = 0;
- for (i = 0; i < sizeof (tests) / sizeof (tests[i]); ++i)
+ for (size_t i = 0; i < tests_size; i++)
{
re_set_syntax (tests[i].syntax);
memset (&r, 0, sizeof (r));
- if (re_compile_pattern (tests[i].regex, strlen (tests[i].regex), &r))
- {
- printf ("re_compile_pattern %zd failed\n", i);
- ret = 1;
- continue;
- }
+ const char *re = re_compile_pattern (tests[i].regex,
+ strlen (tests[i].regex), &r);
+ TEST_VERIFY (re == NULL);
+ if (re != NULL)
+ continue;
+
size_t len = strlen (tests[i].string);
int rv = re_search (&r, tests[i].string, len, 0, len, NULL);
- if (rv != tests[i].retval)
- {
- printf ("re_search %zd unexpected value %d != %d\n",
- i, rv, tests[i].retval);
- ret = 1;
- }
+ TEST_VERIFY (rv == tests[i].retval);
+ if (test_verbose > 0)
+ printf ("info: i=%zu rv=%d expected=%d\n", i, rv, tests[i].retval);
+
regfree (&r);
}
- return ret;
+
+ return 0;
}
+
+#include <support/test-driver.c>
diff --git a/posix/bug-regex37.c b/posix/bug-regex37.c
new file mode 100644
index 0000000000..87a0916914
--- /dev/null
+++ b/posix/bug-regex37.c
@@ -0,0 +1,32 @@
+/* Test regcomp return for invalid expression (BZ #21163).
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <regex.h>
+
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ char const pattern[] = "()*)|\\1)*";
+ regex_t r;
+ TEST_VERIFY_EXIT (regcomp (&r, pattern, REG_EXTENDED) == REG_ESUBREG);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/bug-regex38.c b/posix/bug-regex38.c
new file mode 100644
index 0000000000..cb0eb7d214
--- /dev/null
+++ b/posix/bug-regex38.c
@@ -0,0 +1,32 @@
+/* Diagnose invalid back-reference in the ERE '()|\1' (BZ #18986).
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <regex.h>
+
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ char const pattern[] = "0|()0|\\1|0";
+ regex_t r;
+ TEST_VERIFY_EXIT (regcomp (&r, pattern, REG_EXTENDED) == REG_ESUBREG);
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/regcomp.c b/posix/regcomp.c
index f5c09febb9..7b5ddaad0c 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -15,9 +15,7 @@
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <stdint.h>
+ <https://www.gnu.org/licenses/>. */
#ifdef _LIBC
# include <locale/weight.h>
@@ -51,14 +49,14 @@ static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,
static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
-static int duplicate_node (re_dfa_t *dfa, int org_idx, unsigned int constraint);
-static int search_duplicated_node (const re_dfa_t *dfa, int org_node,
+static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint);
+static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
unsigned int constraint);
static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
- int node, int root);
+ Idx node, bool root);
static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
-static int fetch_number (re_string_t *input, re_token_t *token,
+static Idx fetch_number (re_string_t *input, re_token_t *token,
reg_syntax_t syntax);
static int peek_token (re_token_t *token, re_string_t *input,
reg_syntax_t syntax);
@@ -66,16 +64,16 @@ static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
reg_syntax_t syntax, reg_errcode_t *err);
static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
re_token_t *token, reg_syntax_t syntax,
- int nest, reg_errcode_t *err);
+ Idx nest, reg_errcode_t *err);
static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
re_token_t *token, reg_syntax_t syntax,
- int nest, reg_errcode_t *err);
+ Idx nest, reg_errcode_t *err);
static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
re_token_t *token, reg_syntax_t syntax,
- int nest, reg_errcode_t *err);
+ Idx nest, reg_errcode_t *err);
static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
re_token_t *token, reg_syntax_t syntax,
- int nest, reg_errcode_t *err);
+ Idx nest, reg_errcode_t *err);
static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
re_dfa_t *dfa, re_token_t *token,
reg_syntax_t syntax, reg_errcode_t *err);
@@ -87,34 +85,34 @@ static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
re_token_t *token, int token_len,
re_dfa_t *dfa,
reg_syntax_t syntax,
- int accept_hyphen);
+ bool accept_hyphen);
static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
re_string_t *regexp,
re_token_t *token);
#ifdef RE_ENABLE_I18N
static reg_errcode_t build_equiv_class (bitset_t sbcset,
re_charset_t *mbcset,
- int *equiv_class_alloc,
+ Idx *equiv_class_alloc,
const unsigned char *name);
static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
bitset_t sbcset,
re_charset_t *mbcset,
- int *char_class_alloc,
- const unsigned char *class_name,
+ Idx *char_class_alloc,
+ const char *class_name,
reg_syntax_t syntax);
#else /* not RE_ENABLE_I18N */
static reg_errcode_t build_equiv_class (bitset_t sbcset,
const unsigned char *name);
static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
bitset_t sbcset,
- const unsigned char *class_name,
+ const char *class_name,
reg_syntax_t syntax);
#endif /* not RE_ENABLE_I18N */
static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
RE_TRANSLATE_TYPE trans,
- const unsigned char *class_name,
- const unsigned char *extra,
- int non_match, reg_errcode_t *err);
+ const char *class_name,
+ const char *extra,
+ bool non_match, reg_errcode_t *err);
static bin_tree_t *create_tree (re_dfa_t *dfa,
bin_tree_t *left, bin_tree_t *right,
re_token_type_t type);
@@ -131,7 +129,7 @@ static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
POSIX doesn't require that we do anything for REG_NOERROR,
but why not be nice? */
-const char __re_error_msgid[] attribute_hidden =
+static const char __re_error_msgid[] =
{
#define REG_NOERROR_IDX 0
gettext_noop ("Success") /* REG_NOERROR */
@@ -155,9 +153,9 @@ const char __re_error_msgid[] attribute_hidden =
gettext_noop ("Invalid back reference") /* REG_ESUBREG */
"\0"
#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference")
- gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
+ gettext_noop ("Unmatched [, [^, [:, [., or [=") /* REG_EBRACK */
"\0"
-#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
+#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [, [^, [:, [., or [=")
gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
"\0"
#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
@@ -185,7 +183,7 @@ const char __re_error_msgid[] attribute_hidden =
gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
};
-const size_t __re_error_msgid_idx[] attribute_hidden =
+static const size_t __re_error_msgid_idx[] =
{
REG_NOERROR_IDX,
REG_NOMATCH_IDX,
@@ -269,7 +267,7 @@ weak_alias (__re_set_syntax, re_set_syntax)
int
re_compile_fastmap (struct re_pattern_buffer *bufp)
{
- re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+ re_dfa_t *dfa = bufp->buffer;
char *fastmap = bufp->fastmap;
memset (fastmap, '\0', sizeof (char) * SBC_MAX);
@@ -303,12 +301,12 @@ static void
re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
char *fastmap)
{
- re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
- int node_cnt;
- int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
+ re_dfa_t *dfa = bufp->buffer;
+ Idx node_cnt;
+ bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
{
- int node = init_state->nodes.elems[node_cnt];
+ Idx node = init_state->nodes.elems[node_cnt];
re_token_type_t type = dfa->nodes[node].type;
if (type == CHARACTER)
@@ -317,7 +315,8 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
#ifdef RE_ENABLE_I18N
if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
{
- unsigned char *buf = alloca (dfa->mb_cur_max), *p;
+ unsigned char buf[MB_LEN_MAX];
+ unsigned char *p;
wchar_t wc;
mbstate_t state;
@@ -332,7 +331,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
&state) == p - buf
&& (__wcrtomb ((char *) buf, __towlower (wc), &state)
!= (size_t) -1))
- re_set_fastmap (fastmap, 0, buf[0]);
+ re_set_fastmap (fastmap, false, buf[0]);
}
#endif
}
@@ -352,7 +351,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
else if (type == COMPLEX_BRACKET)
{
re_charset_t *cset = dfa->nodes[node].opr.mbcset;
- int i;
+ Idx i;
# ifdef _LIBC
/* See if we have to try all bytes which start multiple collation
@@ -465,7 +464,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
the return codes and their meanings.) */
int
-regcomp (regex_t *__restrict preg, const char *__restrict pattern, int cflags)
+regcomp (regex_t *_Restrict_ preg, const char *_Restrict_ pattern, int cflags)
{
reg_errcode_t ret;
reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
@@ -525,7 +524,7 @@ weak_alias (__regcomp, regcomp)
from either regcomp or regexec. We don't use PREG here. */
size_t
-regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf,
+regerror (int errcode, const regex_t *_Restrict_ preg, char *_Restrict_ errbuf,
size_t errbuf_size)
{
const char *msg;
@@ -546,17 +545,13 @@ regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf,
if (BE (errbuf_size != 0, 1))
{
+ size_t cpy_size = msg_size;
if (BE (msg_size > errbuf_size, 0))
{
-#if defined HAVE_MEMPCPY || defined _LIBC
- *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
-#else
- memcpy (errbuf, msg, errbuf_size - 1);
- errbuf[errbuf_size - 1] = 0;
-#endif
+ cpy_size = errbuf_size - 1;
+ errbuf[cpy_size] = '\0';
}
- else
- memcpy (errbuf, msg, msg_size);
+ memcpy (errbuf, msg, cpy_size);
}
return msg_size;
@@ -574,7 +569,23 @@ weak_alias (__regerror, regerror)
static const bitset_t utf8_sb_map =
{
/* Set the first 128 bits. */
+# if defined __GNUC__ && !defined __STRICT_ANSI__
[0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX
+# else
+# if 4 * BITSET_WORD_BITS < ASCII_CHARS
+# error "bitset_word_t is narrower than 32 bits"
+# elif 3 * BITSET_WORD_BITS < ASCII_CHARS
+ BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX,
+# elif 2 * BITSET_WORD_BITS < ASCII_CHARS
+ BITSET_WORD_MAX, BITSET_WORD_MAX,
+# elif 1 * BITSET_WORD_BITS < ASCII_CHARS
+ BITSET_WORD_MAX,
+# endif
+ (BITSET_WORD_MAX
+ >> (SBC_MAX % BITSET_WORD_BITS == 0
+ ? 0
+ : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS))
+# endif
};
#endif
@@ -582,7 +593,7 @@ static const bitset_t utf8_sb_map =
static void
free_dfa_content (re_dfa_t *dfa)
{
- int i, j;
+ Idx i, j;
if (dfa->nodes)
for (i = 0; i < dfa->nodes_len; ++i)
@@ -632,9 +643,12 @@ free_dfa_content (re_dfa_t *dfa)
void
regfree (regex_t *preg)
{
- re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+ re_dfa_t *dfa = preg->buffer;
if (BE (dfa != NULL, 1))
- free_dfa_content (dfa);
+ {
+ lock_fini (dfa->lock);
+ free_dfa_content (dfa);
+ }
preg->buffer = NULL;
preg->allocated = 0;
@@ -687,7 +701,7 @@ re_comp (const char *s)
if (re_comp_buf.fastmap == NULL)
{
- re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
+ re_comp_buf.fastmap = re_malloc (char, SBC_MAX);
if (re_comp_buf.fastmap == NULL)
return (char *) gettext (__re_error_msgid
+ __re_error_msgid_idx[(int) REG_ESPACE]);
@@ -704,7 +718,7 @@ re_comp (const char *s)
if (!ret)
return NULL;
- /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ /* Yes, we're discarding 'const' here if !HAVE_LIBINTL. */
return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
}
@@ -739,7 +753,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
preg->regs_allocated = REGS_UNALLOCATED;
/* Initialize the dfa. */
- dfa = (re_dfa_t *) preg->buffer;
+ dfa = preg->buffer;
if (BE (preg->allocated < sizeof (re_dfa_t), 0))
{
/* If zero allocated, but buffer is non-null, try to realloc
@@ -750,11 +764,13 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
if (dfa == NULL)
return REG_ESPACE;
preg->allocated = sizeof (re_dfa_t);
- preg->buffer = (unsigned char *) dfa;
+ preg->buffer = dfa;
}
preg->used = sizeof (re_dfa_t);
err = init_dfa (dfa, length);
+ if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0))
+ err = REG_ESPACE;
if (BE (err != REG_NOERROR, 0))
{
free_dfa_content (dfa);
@@ -768,15 +784,14 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
strncpy (dfa->re_str, pattern, length + 1);
#endif
- __libc_lock_init (dfa->lock);
-
err = re_string_construct (&regexp, pattern, length, preg->translate,
- syntax & RE_ICASE, dfa);
+ (syntax & RE_ICASE) != 0, dfa);
if (BE (err != REG_NOERROR, 0))
{
re_compile_internal_free_return:
free_workarea_compile (preg);
re_string_destruct (&regexp);
+ lock_fini (dfa->lock);
free_dfa_content (dfa);
preg->buffer = NULL;
preg->allocated = 0;
@@ -809,6 +824,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
if (BE (err != REG_NOERROR, 0))
{
+ lock_fini (dfa->lock);
free_dfa_content (dfa);
preg->buffer = NULL;
preg->allocated = 0;
@@ -823,18 +839,32 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
static reg_errcode_t
init_dfa (re_dfa_t *dfa, size_t pat_len)
{
- unsigned int table_size;
+ __re_size_t table_size;
#ifndef _LIBC
- char *codeset_name;
+ const char *codeset_name;
+#endif
+#ifdef RE_ENABLE_I18N
+ size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));
+#else
+ size_t max_i18n_object_size = 0;
#endif
+ size_t max_object_size =
+ MAX (sizeof (struct re_state_table_entry),
+ MAX (sizeof (re_token_t),
+ MAX (sizeof (re_node_set),
+ MAX (sizeof (regmatch_t),
+ max_i18n_object_size))));
memset (dfa, '\0', sizeof (re_dfa_t));
/* Force allocation of str_tree_storage the first time. */