libroot: Synchronize glibc regex with upstream 2.20.
More recent versions require more changes to adapt.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src system libroot posix glibc regex ;
|
SubDir HAIKU_TOP src system libroot posix glibc regex ;
|
||||||
|
|
||||||
SubDirHdrs $(HAIKU_TOP) headers ;
|
SubDirHdrs $(HAIKU_TOP) headers ;
|
||||||
SubDirCcFlags -D_REGEX_RE_COMP -D_DEFAULT_SOURCE -DHAVE_STDBOOL_H ;
|
SubDirCcFlags -D_REGEX_RE_COMP -D_DEFAULT_SOURCE -DHAVE_STDBOOL_H -DHAVE_STDINT_H ;
|
||||||
|
|
||||||
local architectureObject ;
|
local architectureObject ;
|
||||||
for architectureObject in [ MultiArchSubDirSetup ] {
|
for architectureObject in [ MultiArchSubDirSetup ] {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/* Extended regular expression matching and search library.
|
/* Extended regular expression matching and search library.
|
||||||
Copyright (C) 2002,2003,2004,2005,2006,2007,2009
|
Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||||
Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Isamu Hasegawa <[email protected]>.
|
Contributed by Isamu Hasegawa <[email protected]>.
|
||||||
|
|
||||||
@@ -15,9 +14,14 @@
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with the GNU C Library; if not, write to the Free
|
License along with the GNU C Library; if not, see
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
<http://www.gnu.org/licenses/>. */
|
||||||
02111-1307 USA. */
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# include <locale/weight.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
|
static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
|
||||||
size_t length, reg_syntax_t syntax);
|
size_t length, reg_syntax_t syntax);
|
||||||
@@ -121,7 +125,7 @@ static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
|
|||||||
static void free_token (re_token_t *node);
|
static void free_token (re_token_t *node);
|
||||||
static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
|
static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
|
||||||
static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
|
static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
|
||||||
|
|
||||||
/* This table gives an error message for each of the error codes listed
|
/* This table gives an error message for each of the error codes listed
|
||||||
in regex.h. Obviously the order here has to be same as there.
|
in regex.h. Obviously the order here has to be same as there.
|
||||||
POSIX doesn't require that we do anything for REG_NOERROR,
|
POSIX doesn't require that we do anything for REG_NOERROR,
|
||||||
@@ -201,7 +205,7 @@ const size_t __re_error_msgid_idx[] attribute_hidden =
|
|||||||
REG_ESIZE_IDX,
|
REG_ESIZE_IDX,
|
||||||
REG_ERPAREN_IDX
|
REG_ERPAREN_IDX
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Entry points for GNU code. */
|
/* Entry points for GNU code. */
|
||||||
|
|
||||||
/* re_compile_pattern is the GNU regular expression compiler: it
|
/* re_compile_pattern is the GNU regular expression compiler: it
|
||||||
@@ -377,7 +381,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
|
|||||||
applies to multibyte character sets; for single byte character
|
applies to multibyte character sets; for single byte character
|
||||||
sets, the SIMPLE_BRACKET again suffices. */
|
sets, the SIMPLE_BRACKET again suffices. */
|
||||||
if (dfa->mb_cur_max > 1
|
if (dfa->mb_cur_max > 1
|
||||||
&& (cset->nchar_classes || cset->non_match
|
&& (cset->nchar_classes || cset->non_match || cset->nranges
|
||||||
# ifdef _LIBC
|
# ifdef _LIBC
|
||||||
|| cset->nequiv_classes
|
|| cset->nequiv_classes
|
||||||
# endif /* _LIBC */
|
# endif /* _LIBC */
|
||||||
@@ -427,7 +431,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Entry point for POSIX code. */
|
/* Entry point for POSIX code. */
|
||||||
/* regcomp takes a regular expression as a string and compiles it.
|
/* regcomp takes a regular expression as a string and compiles it.
|
||||||
|
|
||||||
@@ -653,7 +657,7 @@ regfree (preg)
|
|||||||
#ifdef _LIBC
|
#ifdef _LIBC
|
||||||
weak_alias (__regfree, regfree)
|
weak_alias (__regfree, regfree)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Entry points compatible with 4.2 BSD regex library. We don't define
|
/* Entry points compatible with 4.2 BSD regex library. We don't define
|
||||||
them unless specifically requested. */
|
them unless specifically requested. */
|
||||||
|
|
||||||
@@ -722,7 +726,7 @@ libc_freeres_fn (free_mem)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* _REGEX_RE_COMP */
|
#endif /* _REGEX_RE_COMP */
|
||||||
|
|
||||||
/* Internal entry point.
|
/* Internal entry point.
|
||||||
Compile the regular expression PATTERN, whose length is LENGTH.
|
Compile the regular expression PATTERN, whose length is LENGTH.
|
||||||
SYNTAX indicate regular expression's syntax. */
|
SYNTAX indicate regular expression's syntax. */
|
||||||
@@ -927,12 +931,49 @@ static void
|
|||||||
internal_function
|
internal_function
|
||||||
init_word_char (re_dfa_t *dfa)
|
init_word_char (re_dfa_t *dfa)
|
||||||
{
|
{
|
||||||
int i, j, ch;
|
|
||||||
dfa->word_ops_used = 1;
|
dfa->word_ops_used = 1;
|
||||||
for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
|
{
|
||||||
|
int i = 0;
|
||||||
|
int ch = 0;
|
||||||
|
if (BE (dfa->map_notascii == 0, 1))
|
||||||
|
{
|
||||||
|
if (sizeof (dfa->word_char[0]) == 8)
|
||||||
|
{
|
||||||
|
/* The extra temporaries here avoid "implicitly truncated"
|
||||||
|
warnings in the case when this is dead code, i.e. 32-bit. */
|
||||||
|
const uint64_t wc0 = UINT64_C (0x03ff000000000000);
|
||||||
|
const uint64_t wc1 = UINT64_C (0x07fffffe87fffffe);
|
||||||
|
dfa->word_char[0] = wc0;
|
||||||
|
dfa->word_char[1] = wc1;
|
||||||
|
i = 2;
|
||||||
|
}
|
||||||
|
else if (sizeof (dfa->word_char[0]) == 4)
|
||||||
|
{
|
||||||
|
dfa->word_char[0] = UINT32_C (0x00000000);
|
||||||
|
dfa->word_char[1] = UINT32_C (0x03ff0000);
|
||||||
|
dfa->word_char[2] = UINT32_C (0x87fffffe);
|
||||||
|
dfa->word_char[3] = UINT32_C (0x07fffffe);
|
||||||
|
i = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
ch = 128;
|
||||||
|
|
||||||
|
if (BE (dfa->is_utf8, 1))
|
||||||
|
{
|
||||||
|
memset (&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (; i < BITSET_WORDS; ++i)
|
||||||
for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
|
for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
|
||||||
if (isalnum (ch) || ch == '_')
|
if (isalnum (ch) || ch == '_')
|
||||||
dfa->word_char[i] |= (bitset_word_t) 1 << j;
|
dfa->word_char[i] |= (bitset_word_t) 1 << j;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the work area which are only used while compiling. */
|
/* Free the work area which are only used while compiling. */
|
||||||
@@ -1000,7 +1041,11 @@ create_initial_state (re_dfa_t *dfa)
|
|||||||
int dest_idx = dfa->edests[node_idx].elems[0];
|
int dest_idx = dfa->edests[node_idx].elems[0];
|
||||||
if (!re_node_set_contains (&init_nodes, dest_idx))
|
if (!re_node_set_contains (&init_nodes, dest_idx))
|
||||||
{
|
{
|
||||||
re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
|
reg_errcode_t err = re_node_set_merge (&init_nodes,
|
||||||
|
dfa->eclosures
|
||||||
|
+ dest_idx);
|
||||||
|
if (err != REG_NOERROR)
|
||||||
|
return err;
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1032,7 +1077,7 @@ create_initial_state (re_dfa_t *dfa)
|
|||||||
re_node_set_free (&init_nodes);
|
re_node_set_free (&init_nodes);
|
||||||
return REG_NOERROR;
|
return REG_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RE_ENABLE_I18N
|
#ifdef RE_ENABLE_I18N
|
||||||
/* If it is possible to do searching in single byte encoding instead of UTF-8
|
/* If it is possible to do searching in single byte encoding instead of UTF-8
|
||||||
to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
|
to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
|
||||||
@@ -1104,7 +1149,7 @@ optimize_utf8 (re_dfa_t *dfa)
|
|||||||
dfa->has_mb_node = dfa->nbackref > 0 || has_period;
|
dfa->has_mb_node = dfa->nbackref > 0 || has_period;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Analyze the structure tree, and calculate "first", "next", "edest",
|
/* Analyze the structure tree, and calculate "first", "next", "edest",
|
||||||
"eclosure", and "inveclosure". */
|
"eclosure", and "inveclosure". */
|
||||||
|
|
||||||
@@ -1415,7 +1460,7 @@ link_nfa_nodes (void *extra, bin_tree_t *node)
|
|||||||
case OP_BACK_REF:
|
case OP_BACK_REF:
|
||||||
dfa->nexts[idx] = node->next->node_idx;
|
dfa->nexts[idx] = node->next->node_idx;
|
||||||
if (node->token.type == OP_BACK_REF)
|
if (node->token.type == OP_BACK_REF)
|
||||||
re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
|
err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1643,9 +1688,10 @@ static reg_errcode_t
|
|||||||
calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root)
|
calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root)
|
||||||
{
|
{
|
||||||
reg_errcode_t err;
|
reg_errcode_t err;
|
||||||
int i, incomplete;
|
int i;
|
||||||
re_node_set eclosure;
|
re_node_set eclosure;
|
||||||
incomplete = 0;
|
int ret;
|
||||||
|
int incomplete = 0;
|
||||||
err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
|
err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
|
||||||
if (BE (err != REG_NOERROR, 0))
|
if (BE (err != REG_NOERROR, 0))
|
||||||
return err;
|
return err;
|
||||||
@@ -1690,7 +1736,9 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root)
|
|||||||
else
|
else
|
||||||
eclosure_elem = dfa->eclosures[edest];
|
eclosure_elem = dfa->eclosures[edest];
|
||||||
/* Merge the epsilon closure of `edest'. */
|
/* Merge the epsilon closure of `edest'. */
|
||||||
re_node_set_merge (&eclosure, &eclosure_elem);
|
err = re_node_set_merge (&eclosure, &eclosure_elem);
|
||||||
|
if (BE (err != REG_NOERROR, 0))
|
||||||
|
return err;
|
||||||
/* If the epsilon closure of `edest' is incomplete,
|
/* If the epsilon closure of `edest' is incomplete,
|
||||||
the epsilon closure of this node is also incomplete. */
|
the epsilon closure of this node is also incomplete. */
|
||||||
if (dfa->eclosures[edest].nelem == 0)
|
if (dfa->eclosures[edest].nelem == 0)
|
||||||
@@ -1700,8 +1748,10 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Epsilon closures include itself. */
|
/* An epsilon closure includes itself. */
|
||||||
re_node_set_insert (&eclosure, node);
|
ret = re_node_set_insert (&eclosure, node);
|
||||||
|
if (BE (ret < 0, 0))
|
||||||
|
return REG_ESPACE;
|
||||||
if (incomplete && !root)
|
if (incomplete && !root)
|
||||||
dfa->eclosures[node].nelem = 0;
|
dfa->eclosures[node].nelem = 0;
|
||||||
else
|
else
|
||||||
@@ -1709,7 +1759,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root)
|
|||||||
*new_set = eclosure;
|
*new_set = eclosure;
|
||||||
return REG_NOERROR;
|
return REG_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions for token which are used in the parser. */
|
/* Functions for token which are used in the parser. */
|
||||||
|
|
||||||
/* Fetch a token from INPUT.
|
/* Fetch a token from INPUT.
|
||||||
@@ -2046,7 +2096,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Functions for parser. */
|
/* Functions for parser. */
|
||||||
|
|
||||||
/* Entry point of the parser.
|
/* Entry point of the parser.
|
||||||
@@ -2113,8 +2163,12 @@ parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
|
|||||||
{
|
{
|
||||||
branch = parse_branch (regexp, preg, token, syntax, nest, err);
|
branch = parse_branch (regexp, preg, token, syntax, nest, err);
|
||||||
if (BE (*err != REG_NOERROR && branch == NULL, 0))
|
if (BE (*err != REG_NOERROR && branch == NULL, 0))
|
||||||
|
{
|
||||||
|
if (tree != NULL)
|
||||||
|
postorder (tree, free_tree, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
branch = NULL;
|
branch = NULL;
|
||||||
tree = create_tree (dfa, tree, branch, OP_ALT);
|
tree = create_tree (dfa, tree, branch, OP_ALT);
|
||||||
@@ -2152,16 +2206,21 @@ parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,
|
|||||||
exp = parse_expression (regexp, preg, token, syntax, nest, err);
|
exp = parse_expression (regexp, preg, token, syntax, nest, err);
|
||||||
if (BE (*err != REG_NOERROR && exp == NULL, 0))
|
if (BE (*err != REG_NOERROR && exp == NULL, 0))
|
||||||
{
|
{
|
||||||
|
if (tree != NULL)
|
||||||
|
postorder (tree, free_tree, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (tree != NULL && exp != NULL)
|
if (tree != NULL && exp != NULL)
|
||||||
{
|
{
|
||||||
tree = create_tree (dfa, tree, exp, CONCAT);
|
bin_tree_t *newtree = create_tree (dfa, tree, exp, CONCAT);
|
||||||
if (tree == NULL)
|
if (newtree == NULL)
|
||||||
{
|
{
|
||||||
|
postorder (exp, free_tree, NULL);
|
||||||
|
postorder (tree, free_tree, NULL);
|
||||||
*err = REG_ESPACE;
|
*err = REG_ESPACE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
tree = newtree;
|
||||||
}
|
}
|
||||||
else if (tree == NULL)
|
else if (tree == NULL)
|
||||||
tree = exp;
|
tree = exp;
|
||||||
@@ -2369,14 +2428,21 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
|
|||||||
while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
|
while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
|
||||||
|| token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
|
|| token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
|
||||||
{
|
{
|
||||||
tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
|
bin_tree_t *dup_tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
|
||||||
if (BE (*err != REG_NOERROR && tree == NULL, 0))
|
if (BE (*err != REG_NOERROR && dup_tree == NULL, 0))
|
||||||
|
{
|
||||||
|
if (tree != NULL)
|
||||||
|
postorder (tree, free_tree, NULL);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
tree = dup_tree;
|
||||||
/* In BRE consecutive duplications are not allowed. */
|
/* In BRE consecutive duplications are not allowed. */
|
||||||
if ((syntax & RE_CONTEXT_INVALID_DUP)
|
if ((syntax & RE_CONTEXT_INVALID_DUP)
|
||||||
&& (token->type == OP_DUP_ASTERISK
|
&& (token->type == OP_DUP_ASTERISK
|
||||||
|| token->type == OP_OPEN_DUP_NUM))
|
|| token->type == OP_OPEN_DUP_NUM))
|
||||||
{
|
{
|
||||||
|
if (tree != NULL)
|
||||||
|
postorder (tree, free_tree, NULL);
|
||||||
*err = REG_BADRPT;
|
*err = REG_BADRPT;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -2410,7 +2476,11 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
|
|||||||
{
|
{
|
||||||
tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
|
tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
|
||||||
if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
|
if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
|
||||||
|
{
|
||||||
|
if (tree != NULL)
|
||||||
|
postorder (tree, free_tree, NULL);
|
||||||
*err = REG_EPAREN;
|
*err = REG_EPAREN;
|
||||||
|
}
|
||||||
if (BE (*err != REG_NOERROR, 0))
|
if (BE (*err != REG_NOERROR, 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -2521,6 +2591,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
|
|||||||
|
|
||||||
/* Duplicate ELEM before it is marked optional. */
|
/* Duplicate ELEM before it is marked optional. */
|
||||||
elem = duplicate_tree (elem, dfa);
|
elem = duplicate_tree (elem, dfa);
|
||||||
|
if (BE (elem == NULL, 0))
|
||||||
|
goto parse_dup_op_espace;
|
||||||
old_tree = tree;
|
old_tree = tree;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2728,41 +2800,30 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
|
|
||||||
/* Local function for parse_bracket_exp used in _LIBC environement.
|
/* Local function for parse_bracket_exp used in _LIBC environement.
|
||||||
Seek the collating symbol entry correspondings to NAME.
|
Seek the collating symbol entry correspondings to NAME.
|
||||||
Return the index of the symbol in the SYMB_TABLE. */
|
Return the index of the symbol in the SYMB_TABLE,
|
||||||
|
or -1 if not found. */
|
||||||
|
|
||||||
auto inline int32_t
|
auto inline int32_t
|
||||||
__attribute ((always_inline))
|
__attribute ((always_inline))
|
||||||
seek_collating_symbol_entry (name, name_len)
|
seek_collating_symbol_entry (const unsigned char *name, size_t name_len)
|
||||||
const unsigned char *name;
|
|
||||||
size_t name_len;
|
|
||||||
{
|
{
|
||||||
int32_t hash = elem_hash ((const char *) name, name_len);
|
int32_t elem;
|
||||||
int32_t elem = hash % table_size;
|
|
||||||
|
for (elem = 0; elem < table_size; elem++)
|
||||||
if (symb_table[2 * elem] != 0)
|
if (symb_table[2 * elem] != 0)
|
||||||
{
|
{
|
||||||
int32_t second = hash % (table_size - 2) + 1;
|
int32_t idx = symb_table[2 * elem + 1];
|
||||||
|
/* Skip the name of collating element name. */
|
||||||
do
|
idx += 1 + extra[idx];
|
||||||
{
|
if (/* Compare the length of the name. */
|
||||||
/* First compare the hashing value. */
|
name_len == extra[idx]
|
||||||
if (symb_table[2 * elem] == hash
|
|
||||||
/* Compare the length of the name. */
|
|
||||||
&& name_len == extra[symb_table[2 * elem + 1]]
|
|
||||||
/* Compare the name. */
|
/* Compare the name. */
|
||||||
&& memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
|
&& memcmp (name, &extra[idx + 1], name_len) == 0)
|
||||||
name_len) == 0)
|
|
||||||
{
|
|
||||||
/* Yep, this is the entry. */
|
/* Yep, this is the entry. */
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next entry. */
|
|
||||||
elem += second;
|
|
||||||
}
|
|
||||||
while (symb_table[2 * elem] != 0);
|
|
||||||
}
|
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Local function for parse_bracket_exp used in _LIBC environment.
|
/* Local function for parse_bracket_exp used in _LIBC environment.
|
||||||
Look up the collation sequence value of BR_ELEM.
|
Look up the collation sequence value of BR_ELEM.
|
||||||
@@ -2770,8 +2831,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
|
|
||||||
auto inline unsigned int
|
auto inline unsigned int
|
||||||
__attribute ((always_inline))
|
__attribute ((always_inline))
|
||||||
lookup_collation_sequence_value (br_elem)
|
lookup_collation_sequence_value (bracket_elem_t *br_elem)
|
||||||
bracket_elem_t *br_elem;
|
|
||||||
{
|
{
|
||||||
if (br_elem->type == SB_CHAR)
|
if (br_elem->type == SB_CHAR)
|
||||||
{
|
{
|
||||||
@@ -2799,7 +2859,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
int32_t elem, idx;
|
int32_t elem, idx;
|
||||||
elem = seek_collating_symbol_entry (br_elem->opr.name,
|
elem = seek_collating_symbol_entry (br_elem->opr.name,
|
||||||
sym_name_len);
|
sym_name_len);
|
||||||
if (symb_table[2 * elem] != 0)
|
if (elem != -1)
|
||||||
{
|
{
|
||||||
/* We found the entry. */
|
/* We found the entry. */
|
||||||
idx = symb_table[2 * elem + 1];
|
idx = symb_table[2 * elem + 1];
|
||||||
@@ -2817,7 +2877,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
/* Return the collation sequence value. */
|
/* Return the collation sequence value. */
|
||||||
return *(unsigned int *) (extra + idx);
|
return *(unsigned int *) (extra + idx);
|
||||||
}
|
}
|
||||||
else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
|
else if (sym_name_len == 1)
|
||||||
{
|
{
|
||||||
/* No valid character. Match it as a single byte
|
/* No valid character. Match it as a single byte
|
||||||
character. */
|
character. */
|
||||||
@@ -2839,11 +2899,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
|
|
||||||
auto inline reg_errcode_t
|
auto inline reg_errcode_t
|
||||||
__attribute ((always_inline))
|
__attribute ((always_inline))
|
||||||
build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
|
build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc,
|
||||||
re_charset_t *mbcset;
|
bracket_elem_t *start_elem, bracket_elem_t *end_elem)
|
||||||
int *range_alloc;
|
|
||||||
bitset_t sbcset;
|
|
||||||
bracket_elem_t *start_elem, *end_elem;
|
|
||||||
{
|
{
|
||||||
unsigned int ch;
|
unsigned int ch;
|
||||||
uint32_t start_collseq;
|
uint32_t start_collseq;
|
||||||
@@ -2922,25 +2979,22 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
|
|
||||||
auto inline reg_errcode_t
|
auto inline reg_errcode_t
|
||||||
__attribute ((always_inline))
|
__attribute ((always_inline))
|
||||||
build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
|
build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset,
|
||||||
re_charset_t *mbcset;
|
int *coll_sym_alloc, const unsigned char *name)
|
||||||
int *coll_sym_alloc;
|
|
||||||
bitset_t sbcset;
|
|
||||||
const unsigned char *name;
|
|
||||||
{
|
{
|
||||||
int32_t elem, idx;
|
int32_t elem, idx;
|
||||||
size_t name_len = strlen ((const char *) name);
|
size_t name_len = strlen ((const char *) name);
|
||||||
if (nrules != 0)
|
if (nrules != 0)
|
||||||
{
|
{
|
||||||
elem = seek_collating_symbol_entry (name, name_len);
|
elem = seek_collating_symbol_entry (name, name_len);
|
||||||
if (symb_table[2 * elem] != 0)
|
if (elem != -1)
|
||||||
{
|
{
|
||||||
/* We found the entry. */
|
/* We found the entry. */
|
||||||
idx = symb_table[2 * elem + 1];
|
idx = symb_table[2 * elem + 1];
|
||||||
/* Skip the name of collating element name. */
|
/* Skip the name of collating element name. */
|
||||||
idx += 1 + extra[idx];
|
idx += 1 + extra[idx];
|
||||||
}
|
}
|
||||||
else if (symb_table[2 * elem] == 0 && name_len == 1)
|
else if (name_len == 1)
|
||||||
{
|
{
|
||||||
/* No valid character, treat it as a normal
|
/* No valid character, treat it as a normal
|
||||||
character. */
|
character. */
|
||||||
@@ -3020,6 +3074,10 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
|
|||||||
if (BE (sbcset == NULL, 0))
|
if (BE (sbcset == NULL, 0))
|
||||||
#endif /* RE_ENABLE_I18N */
|
#endif /* RE_ENABLE_I18N */
|
||||||
{
|
{
|
||||||
|
re_free (sbcset);
|
||||||
|
#ifdef RE_ENABLE_I18N
|
||||||
|
re_free (mbcset);
|
||||||
|
#endif
|
||||||
*err = REG_ESPACE;
|
*err = REG_ESPACE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -3377,8 +3435,6 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
|
|||||||
int32_t idx1, idx2;
|
int32_t idx1, idx2;
|
||||||
unsigned int ch;
|
unsigned int ch;
|
||||||
size_t len;
|
size_t len;
|
||||||
/* This #include defines a local function! */
|
|
||||||
# include <locale/weight.h>
|
|
||||||
/* Calculate the index for equivalence class. */
|
/* Calculate the index for equivalence class. */
|
||||||
cp = name;
|
cp = name;
|
||||||
table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
|
table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
|
||||||
@@ -3388,19 +3444,18 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
|
|||||||
_NL_COLLATE_EXTRAMB);
|
_NL_COLLATE_EXTRAMB);
|
||||||
indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
|
indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
|
||||||
_NL_COLLATE_INDIRECTMB);
|
_NL_COLLATE_INDIRECTMB);
|
||||||
idx1 = findidx (&cp);
|
idx1 = findidx (table, indirect, extra, &cp, -1);
|
||||||
if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
|
if (BE (idx1 == 0 || *cp != '\0', 0))
|
||||||
/* This isn't a valid character. */
|
/* This isn't a valid character. */
|
||||||
return REG_ECOLLATE;
|
return REG_ECOLLATE;
|
||||||
|
|
||||||
/* Build single byte matcing table for this equivalence class. */
|
/* Build single byte matcing table for this equivalence class. */
|
||||||
char_buf[1] = (unsigned char) '\0';
|
|
||||||
len = weights[idx1 & 0xffffff];
|
len = weights[idx1 & 0xffffff];
|
||||||
for (ch = 0; ch < SBC_MAX; ++ch)
|
for (ch = 0; ch < SBC_MAX; ++ch)
|
||||||
{
|
{
|
||||||
char_buf[0] = ch;
|
char_buf[0] = ch;
|
||||||
cp = char_buf;
|
cp = char_buf;
|
||||||
idx2 = findidx (&cp);
|
idx2 = findidx (table, indirect, extra, &cp, 1);
|
||||||
/*
|
/*
|
||||||
idx2 = table[ch];
|
idx2 = table[ch];
|
||||||
*/
|
*/
|
||||||
@@ -3670,7 +3725,7 @@ fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
|
|||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RE_ENABLE_I18N
|
#ifdef RE_ENABLE_I18N
|
||||||
static void
|
static void
|
||||||
free_charset (re_charset_t *cset)
|
free_charset (re_charset_t *cset)
|
||||||
@@ -3686,7 +3741,7 @@ free_charset (re_charset_t *cset)
|
|||||||
re_free (cset);
|
re_free (cset);
|
||||||
}
|
}
|
||||||
#endif /* RE_ENABLE_I18N */
|
#endif /* RE_ENABLE_I18N */
|
||||||
|
|
||||||
/* Functions for binary tree operation. */
|
/* Functions for binary tree operation. */
|
||||||
|
|
||||||
/* Create a tree node. */
|
/* Create a tree node. */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Extended regular expression matching and search library.
|
/* Extended regular expression matching and search library.
|
||||||
Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
|
Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||||
|
|
||||||
@@ -14,9 +14,8 @@
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with the GNU C Library; if not, write to the Free
|
License along with the GNU C Library; if not, see
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
<http://www.gnu.org/licenses/>. */
|
||||||
02111-1307 USA. */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -57,6 +56,9 @@
|
|||||||
#undefs RE_DUP_MAX and sets it to the right value. */
|
#undefs RE_DUP_MAX and sets it to the right value. */
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
/* This header defines the MIN and MAX macros. */
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#include "regex_internal.h"
|
#include "regex_internal.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Extended regular expression matching and search library.
|
/* Extended regular expression matching and search library.
|
||||||
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||||
|
|
||||||
@@ -14,9 +14,8 @@
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with the GNU C Library; if not, write to the Free
|
License along with the GNU C Library; if not, see
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
<http://www.gnu.org/licenses/>. */
|
||||||
02111-1307 USA. */
|
|
||||||
|
|
||||||
static void re_string_construct_common (const char *str, int len,
|
static void re_string_construct_common (const char *str, int len,
|
||||||
re_string_t *pstr,
|
re_string_t *pstr,
|
||||||
@@ -36,7 +35,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
|
|||||||
re_string_reconstruct before using the object. */
|
re_string_reconstruct before using the object. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
|
re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
|
||||||
RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
|
RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
|
||||||
{
|
{
|
||||||
@@ -64,7 +63,7 @@ re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len,
|
|||||||
/* This function allocate the buffers, and initialize them. */
|
/* This function allocate the buffers, and initialize them. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_string_construct (re_string_t *pstr, const char *str, int len,
|
re_string_construct (re_string_t *pstr, const char *str, int len,
|
||||||
RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
|
RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa)
|
||||||
{
|
{
|
||||||
@@ -127,13 +126,20 @@ re_string_construct (re_string_t *pstr, const char *str, int len,
|
|||||||
/* Helper functions for re_string_allocate, and re_string_construct. */
|
/* Helper functions for re_string_allocate, and re_string_construct. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
|
re_string_realloc_buffers (re_string_t *pstr, int new_buf_len)
|
||||||
{
|
{
|
||||||
#ifdef RE_ENABLE_I18N
|
#ifdef RE_ENABLE_I18N
|
||||||
if (pstr->mb_cur_max > 1)
|
if (pstr->mb_cur_max > 1)
|
||||||
{
|
{
|
||||||
wint_t *new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
|
wint_t *new_wcs;
|
||||||
|
|
||||||
|
/* Avoid overflow in realloc. */
|
||||||
|
const size_t max_object_size = MAX (sizeof (wint_t), sizeof (int));
|
||||||
|
if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
|
||||||
|
return REG_ESPACE;
|
||||||
|
|
||||||
|
new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
|
||||||
if (BE (new_wcs == NULL, 0))
|
if (BE (new_wcs == NULL, 0))
|
||||||
return REG_ESPACE;
|
return REG_ESPACE;
|
||||||
pstr->wcs = new_wcs;
|
pstr->wcs = new_wcs;
|
||||||
@@ -230,13 +236,8 @@ build_wcs_buffer (re_string_t *pstr)
|
|||||||
else
|
else
|
||||||
p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
|
p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
|
||||||
mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
|
mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
|
||||||
if (BE (mbclen == (size_t) -2, 0))
|
if (BE (mbclen == (size_t) -1 || mbclen == 0
|
||||||
{
|
|| (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len), 0))
|
||||||
/* The buffer doesn't have enough space, finish to build. */
|
|
||||||
pstr->cur_state = prev_st;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
|
|
||||||
{
|
{
|
||||||
/* We treat these cases as a singlebyte character. */
|
/* We treat these cases as a singlebyte character. */
|
||||||
mbclen = 1;
|
mbclen = 1;
|
||||||
@@ -245,6 +246,12 @@ build_wcs_buffer (re_string_t *pstr)
|
|||||||
wc = pstr->trans[wc];
|
wc = pstr->trans[wc];
|
||||||
pstr->cur_state = prev_st;
|
pstr->cur_state = prev_st;
|
||||||
}
|
}
|
||||||
|
else if (BE (mbclen == (size_t) -2, 0))
|
||||||
|
{
|
||||||
|
/* The buffer doesn't have enough space, finish to build. */
|
||||||
|
pstr->cur_state = prev_st;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write wide character and padding. */
|
/* Write wide character and padding. */
|
||||||
pstr->wcs[byte_idx++] = wc;
|
pstr->wcs[byte_idx++] = wc;
|
||||||
@@ -260,7 +267,7 @@ build_wcs_buffer (re_string_t *pstr)
|
|||||||
but for REG_ICASE. */
|
but for REG_ICASE. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
build_wcs_upper_buffer (re_string_t *pstr)
|
build_wcs_upper_buffer (re_string_t *pstr)
|
||||||
{
|
{
|
||||||
mbstate_t prev_st;
|
mbstate_t prev_st;
|
||||||
@@ -327,9 +334,11 @@ build_wcs_upper_buffer (re_string_t *pstr)
|
|||||||
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
||||||
pstr->wcs[byte_idx++] = WEOF;
|
pstr->wcs[byte_idx++] = WEOF;
|
||||||
}
|
}
|
||||||
else if (mbclen == (size_t) -1 || mbclen == 0)
|
else if (mbclen == (size_t) -1 || mbclen == 0
|
||||||
|
|| (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))
|
||||||
{
|
{
|
||||||
/* It is an invalid character or '\0'. Just use the byte. */
|
/* It is an invalid character, an incomplete character
|
||||||
|
at the end of the string, or '\0'. Just use the byte. */
|
||||||
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
|
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
|
||||||
pstr->mbs[byte_idx] = ch;
|
pstr->mbs[byte_idx] = ch;
|
||||||
/* And also cast it to wide char. */
|
/* And also cast it to wide char. */
|
||||||
@@ -442,7 +451,8 @@ build_wcs_upper_buffer (re_string_t *pstr)
|
|||||||
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
||||||
pstr->wcs[byte_idx++] = WEOF;
|
pstr->wcs[byte_idx++] = WEOF;
|
||||||
}
|
}
|
||||||
else if (mbclen == (size_t) -1 || mbclen == 0)
|
else if (mbclen == (size_t) -1 || mbclen == 0
|
||||||
|
|| (mbclen == (size_t) -2 && pstr->bufs_len >= pstr->len))
|
||||||
{
|
{
|
||||||
/* It is an invalid character or '\0'. Just use the byte. */
|
/* It is an invalid character or '\0'. Just use the byte. */
|
||||||
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
|
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
|
||||||
@@ -482,18 +492,18 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
|
|||||||
mbstate_t prev_st;
|
mbstate_t prev_st;
|
||||||
int rawbuf_idx;
|
int rawbuf_idx;
|
||||||
size_t mbclen;
|
size_t mbclen;
|
||||||
wchar_t wc = WEOF;
|
wint_t wc = WEOF;
|
||||||
|
|
||||||
/* Skip the characters which are not necessary to check. */
|
/* Skip the characters which are not necessary to check. */
|
||||||
for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
|
for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
|
||||||
rawbuf_idx < new_raw_idx;)
|
rawbuf_idx < new_raw_idx;)
|
||||||
{
|
{
|
||||||
int remain_len;
|
wchar_t wc2;
|
||||||
remain_len = pstr->len - rawbuf_idx;
|
int remain_len = pstr->raw_len - rawbuf_idx;
|
||||||
prev_st = pstr->cur_state;
|
prev_st = pstr->cur_state;
|
||||||
mbclen = __mbrtowc (&wc, (const char *) pstr->raw_mbs + rawbuf_idx,
|
mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
|
||||||
remain_len, &pstr->cur_state);
|
remain_len, &pstr->cur_state);
|
||||||
if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
|
if (BE ((ssize_t) mbclen <= 0, 0))
|
||||||
{
|
{
|
||||||
/* We treat these cases as a single byte character. */
|
/* We treat these cases as a single byte character. */
|
||||||
if (mbclen == 0 || remain_len == 0)
|
if (mbclen == 0 || remain_len == 0)
|
||||||
@@ -503,10 +513,12 @@ re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc)
|
|||||||
mbclen = 1;
|
mbclen = 1;
|
||||||
pstr->cur_state = prev_st;
|
pstr->cur_state = prev_st;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
wc = (wint_t) wc2;
|
||||||
/* Then proceed the next character. */
|
/* Then proceed the next character. */
|
||||||
rawbuf_idx += mbclen;
|
rawbuf_idx += mbclen;
|
||||||
}
|
}
|
||||||
*last_wc = (wint_t) wc;
|
*last_wc = wc;
|
||||||
return rawbuf_idx;
|
return rawbuf_idx;
|
||||||
}
|
}
|
||||||
#endif /* RE_ENABLE_I18N */
|
#endif /* RE_ENABLE_I18N */
|
||||||
@@ -559,7 +571,7 @@ re_string_translate_buffer (re_string_t *pstr)
|
|||||||
convert to upper case in case of REG_ICASE, apply translation. */
|
convert to upper case in case of REG_ICASE, apply translation. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
||||||
{
|
{
|
||||||
int offset = idx - pstr->raw_mbs_idx;
|
int offset = idx - pstr->raw_mbs_idx;
|
||||||
@@ -667,7 +679,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
|||||||
pstr->valid_len - offset);
|
pstr->valid_len - offset);
|
||||||
pstr->valid_len -= offset;
|
pstr->valid_len -= offset;
|
||||||
pstr->valid_raw_len -= offset;
|
pstr->valid_raw_len -= offset;
|
||||||
#if DEBUG
|
#if defined DEBUG && DEBUG
|
||||||
assert (pstr->valid_len > 0);
|
assert (pstr->valid_len > 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -694,7 +706,7 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
|||||||
|
|
||||||
if (pstr->is_utf8)
|
if (pstr->is_utf8)
|
||||||
{
|
{
|
||||||
const unsigned char *raw, *p, *q, *end;
|
const unsigned char *raw, *p, *end;
|
||||||
|
|
||||||
/* Special case UTF-8. Multi-byte chars start with any
|
/* Special case UTF-8. Multi-byte chars start with any
|
||||||
byte other than 0x80 - 0xbf. */
|
byte other than 0x80 - 0xbf. */
|
||||||
@@ -723,18 +735,18 @@ re_string_reconstruct (re_string_t *pstr, int idx, int eflags)
|
|||||||
unsigned char buf[6];
|
unsigned char buf[6];
|
||||||
size_t mbclen;
|
size_t mbclen;
|
||||||
|
|
||||||
q = p;
|
const unsigned char *pp = p;
|
||||||
if (BE (pstr->trans != NULL, 0))
|
if (BE (pstr->trans != NULL, 0))
|
||||||
{
|
{
|
||||||
int i = mlen < 6 ? mlen : 6;
|
int i = mlen < 6 ? mlen : 6;
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
buf[i] = pstr->trans[p[i]];
|
buf[i] = pstr->trans[p[i]];
|
||||||
q = buf;
|
pp = buf;
|
||||||
}
|
}
|
||||||
/* XXX Don't use mbrtowc, we know which conversion
|
/* XXX Don't use mbrtowc, we know which conversion
|
||||||
to use (UTF-8 -> UCS4). */
|
to use (UTF-8 -> UCS4). */
|
||||||
memset (&cur_state, 0, sizeof (cur_state));
|
memset (&cur_state, 0, sizeof (cur_state));
|
||||||
mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
|
mbclen = __mbrtowc (&wc2, (const char *) pp, mlen,
|
||||||
&cur_state);
|
&cur_state);
|
||||||
if (raw + offset - p <= mbclen
|
if (raw + offset - p <= mbclen
|
||||||
&& mbclen < (size_t) -2)
|
&& mbclen < (size_t) -2)
|
||||||
@@ -855,7 +867,7 @@ re_string_peek_byte_case (const re_string_t *pstr, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char
|
static unsigned char
|
||||||
internal_function __attribute ((pure))
|
internal_function
|
||||||
re_string_fetch_byte_case (re_string_t *pstr)
|
re_string_fetch_byte_case (re_string_t *pstr)
|
||||||
{
|
{
|
||||||
if (BE (!pstr->mbs_allocated, 1))
|
if (BE (!pstr->mbs_allocated, 1))
|
||||||
@@ -924,7 +936,7 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
|
|||||||
int wc_idx = idx;
|
int wc_idx = idx;
|
||||||
while(input->wcs[wc_idx] == WEOF)
|
while(input->wcs[wc_idx] == WEOF)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#if defined DEBUG && DEBUG
|
||||||
/* It must not happen. */
|
/* It must not happen. */
|
||||||
assert (wc_idx >= 0);
|
assert (wc_idx >= 0);
|
||||||
#endif
|
#endif
|
||||||
@@ -951,7 +963,7 @@ re_string_context_at (const re_string_t *input, int idx, int eflags)
|
|||||||
/* Functions for set operation. */
|
/* Functions for set operation. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_alloc (re_node_set *set, int size)
|
re_node_set_alloc (re_node_set *set, int size)
|
||||||
{
|
{
|
||||||
set->alloc = size;
|
set->alloc = size;
|
||||||
@@ -963,7 +975,7 @@ re_node_set_alloc (re_node_set *set, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_init_1 (re_node_set *set, int elem)
|
re_node_set_init_1 (re_node_set *set, int elem)
|
||||||
{
|
{
|
||||||
set->alloc = 1;
|
set->alloc = 1;
|
||||||
@@ -979,7 +991,7 @@ re_node_set_init_1 (re_node_set *set, int elem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
|
re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
|
||||||
{
|
{
|
||||||
set->alloc = 2;
|
set->alloc = 2;
|
||||||
@@ -1009,7 +1021,7 @@ re_node_set_init_2 (re_node_set *set, int elem1, int elem2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
|
re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
|
||||||
{
|
{
|
||||||
dest->nelem = src->nelem;
|
dest->nelem = src->nelem;
|
||||||
@@ -1034,7 +1046,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
|
|||||||
Note: We assume dest->elems is NULL, when dest->alloc is 0. */
|
Note: We assume dest->elems is NULL, when dest->alloc is 0. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
|
re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
|
||||||
const re_node_set *src2)
|
const re_node_set *src2)
|
||||||
{
|
{
|
||||||
@@ -1125,7 +1137,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
|
|||||||
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
|
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
|
re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
|
||||||
const re_node_set *src2)
|
const re_node_set *src2)
|
||||||
{
|
{
|
||||||
@@ -1178,7 +1190,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
|
|||||||
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
|
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_merge (re_node_set *dest, const re_node_set *src)
|
re_node_set_merge (re_node_set *dest, const re_node_set *src)
|
||||||
{
|
{
|
||||||
int is, id, sbase, delta;
|
int is, id, sbase, delta;
|
||||||
@@ -1261,7 +1273,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
|
|||||||
return -1 if an error is occured, return 1 otherwise. */
|
return -1 if an error is occured, return 1 otherwise. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_insert (re_node_set *set, int elem)
|
re_node_set_insert (re_node_set *set, int elem)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
@@ -1318,7 +1330,7 @@ re_node_set_insert (re_node_set *set, int elem)
|
|||||||
Return -1 if an error is occured, return 1 otherwise. */
|
Return -1 if an error is occured, return 1 otherwise. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_node_set_insert_last (re_node_set *set, int elem)
|
re_node_set_insert_last (re_node_set *set, int elem)
|
||||||
{
|
{
|
||||||
/* Realloc if we need. */
|
/* Realloc if we need. */
|
||||||
@@ -1404,8 +1416,11 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
|
|||||||
re_node_set *new_edests, *new_eclosures;
|
re_node_set *new_edests, *new_eclosures;
|
||||||
re_token_t *new_nodes;
|
re_token_t *new_nodes;
|
||||||
|
|
||||||
/* Avoid overflows. */
|
/* Avoid overflows in realloc. */
|
||||||
if (BE (new_nodes_alloc < dfa->nodes_alloc, 0))
|
const size_t max_object_size = MAX (sizeof (re_token_t),
|
||||||
|
MAX (sizeof (re_node_set),
|
||||||
|
sizeof (int)));
|
||||||
|
if (BE (SIZE_MAX / max_object_size < new_nodes_alloc, 0))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
|
new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
|
||||||
@@ -1458,7 +1473,7 @@ calc_state_hash (const re_node_set *nodes, unsigned int context)
|
|||||||
optimization. */
|
optimization. */
|
||||||
|
|
||||||
static re_dfastate_t *
|
static re_dfastate_t *
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
|
re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
|
||||||
const re_node_set *nodes)
|
const re_node_set *nodes)
|
||||||
{
|
{
|
||||||
@@ -1502,7 +1517,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
|
|||||||
optimization. */
|
optimization. */
|
||||||
|
|
||||||
static re_dfastate_t *
|
static re_dfastate_t *
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
|
re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
|
||||||
const re_node_set *nodes, unsigned int context)
|
const re_node_set *nodes, unsigned int context)
|
||||||
{
|
{
|
||||||
@@ -1539,6 +1554,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
|
|||||||
indicates the error code if failed. */
|
indicates the error code if failed. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
|
__attribute_warn_unused_result__
|
||||||
register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
|
register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
|
||||||
unsigned int hash)
|
unsigned int hash)
|
||||||
{
|
{
|
||||||
@@ -1554,7 +1570,8 @@ register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
|
|||||||
{
|
{
|
||||||
int elem = newstate->nodes.elems[i];
|
int elem = newstate->nodes.elems[i];
|
||||||
if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
|
if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
|
||||||
re_node_set_insert_last (&newstate->non_eps_nodes, elem);
|
if (re_node_set_insert_last (&newstate->non_eps_nodes, elem) < 0)
|
||||||
|
return REG_ESPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
spot = dfa->state_table + (hash & dfa->state_hash_mask);
|
spot = dfa->state_table + (hash & dfa->state_hash_mask);
|
||||||
@@ -1592,7 +1609,7 @@ free_state (re_dfastate_t *state)
|
|||||||
Return the new state if succeeded, otherwise return NULL. */
|
Return the new state if succeeded, otherwise return NULL. */
|
||||||
|
|
||||||
static re_dfastate_t *
|
static re_dfastate_t *
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
|
create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
|
||||||
unsigned int hash)
|
unsigned int hash)
|
||||||
{
|
{
|
||||||
@@ -1642,7 +1659,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
|
|||||||
Return the new state if succeeded, otherwise return NULL. */
|
Return the new state if succeeded, otherwise return NULL. */
|
||||||
|
|
||||||
static re_dfastate_t *
|
static re_dfastate_t *
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
|
create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
|
||||||
unsigned int context, unsigned int hash)
|
unsigned int context, unsigned int hash)
|
||||||
{
|
{
|
||||||
@@ -1691,7 +1708,9 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
|
|||||||
free_state (newstate);
|
free_state (newstate);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
re_node_set_init_copy (newstate->entrance_nodes, nodes);
|
if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
|
||||||
|
!= REG_NOERROR)
|
||||||
|
return NULL;
|
||||||
nctx_nodes = 0;
|
nctx_nodes = 0;
|
||||||
newstate->has_constraint = 1;
|
newstate->has_constraint = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Extended regular expression matching and search library.
|
/* Extended regular expression matching and search library.
|
||||||
Copyright (C) 2002-2005, 2007, 2008 Free Software Foundation, Inc.
|
Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||||
|
|
||||||
@@ -14,9 +14,8 @@
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with the GNU C Library; if not, write to the Free
|
License along with the GNU C Library; if not, see
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
<http://www.gnu.org/licenses/>. */
|
||||||
02111-1307 USA. */
|
|
||||||
|
|
||||||
#ifndef _REGEX_INTERNAL_H
|
#ifndef _REGEX_INTERNAL_H
|
||||||
#define _REGEX_INTERNAL_H 1
|
#define _REGEX_INTERNAL_H 1
|
||||||
@@ -74,7 +73,7 @@
|
|||||||
# ifdef _LIBC
|
# ifdef _LIBC
|
||||||
# undef gettext
|
# undef gettext
|
||||||
# define gettext(msgid) \
|
# define gettext(msgid) \
|
||||||
INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
|
__dcgettext (_libc_intl_domainname, msgid, LC_MESSAGES)
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define gettext(msgid) (msgid)
|
# define gettext(msgid) (msgid)
|
||||||
@@ -91,7 +90,7 @@
|
|||||||
# define SIZE_MAX ((size_t) -1)
|
# define SIZE_MAX ((size_t) -1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL) || _LIBC
|
#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE) || _LIBC
|
||||||
# define RE_ENABLE_I18N
|
# define RE_ENABLE_I18N
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -99,7 +98,6 @@
|
|||||||
# define BE(expr, val) __builtin_expect (expr, val)
|
# define BE(expr, val) __builtin_expect (expr, val)
|
||||||
#else
|
#else
|
||||||
# define BE(expr, val) (expr)
|
# define BE(expr, val) (expr)
|
||||||
# define inline
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Number of single byte character. */
|
/* Number of single byte character. */
|
||||||
@@ -123,10 +121,8 @@
|
|||||||
# define attribute_hidden
|
# define attribute_hidden
|
||||||
#endif /* not _LIBC */
|
#endif /* not _LIBC */
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#if __GNUC__ < 3 + (__GNUC_MINOR__ < 1)
|
||||||
# define __attribute(arg) __attribute__ (arg)
|
# define __attribute__(arg)
|
||||||
#else
|
|
||||||
# define __attribute(arg)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const char __re_error_msgid[] attribute_hidden;
|
extern const char __re_error_msgid[] attribute_hidden;
|
||||||
@@ -380,10 +376,11 @@ typedef struct re_dfa_t re_dfa_t;
|
|||||||
|
|
||||||
#ifndef _LIBC
|
#ifndef _LIBC
|
||||||
# ifdef __i386__
|
# ifdef __i386__
|
||||||
# define internal_function __attribute ((regparm (3), stdcall))
|
# define internal_function __attribute__ ((regparm (3), stdcall))
|
||||||
# else
|
# else
|
||||||
# define internal_function
|
# define internal_function
|
||||||
# endif
|
# endif
|
||||||
|
# define __attribute_warn_unused_result__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NOT_IN_libc
|
#ifndef NOT_IN_libc
|
||||||
@@ -399,7 +396,7 @@ static void build_upper_buffer (re_string_t *pstr) internal_function;
|
|||||||
static void re_string_translate_buffer (re_string_t *pstr) internal_function;
|
static void re_string_translate_buffer (re_string_t *pstr) internal_function;
|
||||||
static unsigned int re_string_context_at (const re_string_t *input, int idx,
|
static unsigned int re_string_context_at (const re_string_t *input, int idx,
|
||||||
int eflags)
|
int eflags)
|
||||||
internal_function __attribute ((pure));
|
internal_function __attribute__ ((pure));
|
||||||
#endif
|
#endif
|
||||||
#define re_string_peek_byte(pstr, offset) \
|
#define re_string_peek_byte(pstr, offset) \
|
||||||
((pstr)->mbs[(pstr)->cur_idx + offset])
|
((pstr)->mbs[(pstr)->cur_idx + offset])
|
||||||
@@ -664,7 +661,7 @@ struct re_dfa_t
|
|||||||
(re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
|
(re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
|
||||||
#define re_node_set_empty(p) ((p)->nelem = 0)
|
#define re_node_set_empty(p) ((p)->nelem = 0)
|
||||||
#define re_node_set_free(set) re_free ((set)->elems)
|
#define re_node_set_free(set) re_free ((set)->elems)
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -688,7 +685,7 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
/* Inline functions for bitset operation. */
|
/* Inline functions for bitset operation. */
|
||||||
static inline void
|
static void __attribute__ ((unused))
|
||||||
bitset_not (bitset_t set)
|
bitset_not (bitset_t set)
|
||||||
{
|
{
|
||||||
int bitset_i;
|
int bitset_i;
|
||||||
@@ -696,7 +693,7 @@ bitset_not (bitset_t set)
|
|||||||
set[bitset_i] = ~set[bitset_i];
|
set[bitset_i] = ~set[bitset_i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static void __attribute__ ((unused))
|
||||||
bitset_merge (bitset_t dest, const bitset_t src)
|
bitset_merge (bitset_t dest, const bitset_t src)
|
||||||
{
|
{
|
||||||
int bitset_i;
|
int bitset_i;
|
||||||
@@ -704,7 +701,7 @@ bitset_merge (bitset_t dest, const bitset_t src)
|
|||||||
dest[bitset_i] |= src[bitset_i];
|
dest[bitset_i] |= src[bitset_i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static void __attribute__ ((unused))
|
||||||
bitset_mask (bitset_t dest, const bitset_t src)
|
bitset_mask (bitset_t dest, const bitset_t src)
|
||||||
{
|
{
|
||||||
int bitset_i;
|
int bitset_i;
|
||||||
@@ -714,8 +711,8 @@ bitset_mask (bitset_t dest, const bitset_t src)
|
|||||||
|
|
||||||
#ifdef RE_ENABLE_I18N
|
#ifdef RE_ENABLE_I18N
|
||||||
/* Inline functions for re_string. */
|
/* Inline functions for re_string. */
|
||||||
static inline int
|
static int
|
||||||
internal_function __attribute ((pure))
|
internal_function __attribute__ ((pure, unused))
|
||||||
re_string_char_size_at (const re_string_t *pstr, int idx)
|
re_string_char_size_at (const re_string_t *pstr, int idx)
|
||||||
{
|
{
|
||||||
int byte_idx;
|
int byte_idx;
|
||||||
@@ -727,8 +724,8 @@ re_string_char_size_at (const re_string_t *pstr, int idx)
|
|||||||
return byte_idx;
|
return byte_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline wint_t
|
static wint_t
|
||||||
internal_function __attribute ((pure))
|
internal_function __attribute__ ((pure, unused))
|
||||||
re_string_wchar_at (const re_string_t *pstr, int idx)
|
re_string_wchar_at (const re_string_t *pstr, int idx)
|
||||||
{
|
{
|
||||||
if (pstr->mb_cur_max == 1)
|
if (pstr->mb_cur_max == 1)
|
||||||
@@ -737,15 +734,17 @@ re_string_wchar_at (const re_string_t *pstr, int idx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ifndef NOT_IN_libc
|
# ifndef NOT_IN_libc
|
||||||
|
# ifdef _LIBC
|
||||||
|
# include <locale/weight.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
internal_function __attribute ((pure))
|
internal_function __attribute__ ((pure, unused))
|
||||||
re_string_elem_size_at (const re_string_t *pstr, int idx)
|
re_string_elem_size_at (const re_string_t *pstr, int idx)
|
||||||
{
|
{
|
||||||
# ifdef _LIBC
|
# ifdef _LIBC
|
||||||
const unsigned char *p, *extra;
|
const unsigned char *p, *extra;
|
||||||
const int32_t *table, *indirect;
|
const int32_t *table, *indirect;
|
||||||
int32_t tmp;
|
|
||||||
# include <locale/weight.h>
|
|
||||||
uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
|
uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
|
||||||
|
|
||||||
if (nrules != 0)
|
if (nrules != 0)
|
||||||
@@ -756,7 +755,7 @@ re_string_elem_size_at (const re_string_t *pstr, int idx)
|
|||||||
indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
|
indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
|
||||||
_NL_COLLATE_INDIRECTMB);
|
_NL_COLLATE_INDIRECTMB);
|
||||||
p = pstr->mbs + idx;
|
p = pstr->mbs + idx;
|
||||||
tmp = findidx (&p);
|
findidx (table, indirect, extra, &p, pstr->len - idx);
|
||||||
return p - pstr->mbs - idx;
|
return p - pstr->mbs - idx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Extended regular expression matching and search library.
|
/* Extended regular expression matching and search library.
|
||||||
Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||||
|
|
||||||
@@ -14,9 +14,10 @@
|
|||||||
Lesser General Public License for more details.
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with the GNU C Library; if not, write to the Free
|
License along with the GNU C Library; if not, see
|
||||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
<http://www.gnu.org/licenses/>. */
|
||||||
02111-1307 USA. */
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
|
static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
|
||||||
int n) internal_function;
|
int n) internal_function;
|
||||||
@@ -198,7 +199,7 @@ static int group_nodes_into_DFAstates (const re_dfa_t *dfa,
|
|||||||
static int check_node_accept (const re_match_context_t *mctx,
|
static int check_node_accept (const re_match_context_t *mctx,
|
||||||
const re_token_t *node, int idx)
|
const re_token_t *node, int idx)
|
||||||
internal_function;
|
internal_function;
|
||||||
static reg_errcode_t extend_buffers (re_match_context_t *mctx)
|
static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len)
|
||||||
internal_function;
|
internal_function;
|
||||||
|
|
||||||
/* Entry point for POSIX code. */
|
/* Entry point for POSIX code. */
|
||||||
@@ -368,16 +369,16 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
|
|||||||
const char *str;
|
const char *str;
|
||||||
int rval;
|
int rval;
|
||||||
int len = length1 + length2;
|
int len = length1 + length2;
|
||||||
int free_str = 0;
|
char *s = NULL;
|
||||||
|
|
||||||
if (BE (length1 < 0 || length2 < 0 || stop < 0, 0))
|
if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
/* Concatenate the strings. */
|
/* Concatenate the strings. */
|
||||||
if (length2 > 0)
|
if (length2 > 0)
|
||||||
if (length1 > 0)
|
if (length1 > 0)
|
||||||
{
|
{
|
||||||
char *s = re_malloc (char, len);
|
s = re_malloc (char, len);
|
||||||
|
|
||||||
if (BE (s == NULL, 0))
|
if (BE (s == NULL, 0))
|
||||||
return -2;
|
return -2;
|
||||||
@@ -388,17 +389,14 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
|
|||||||
memcpy (s + length1, string2, length2);
|
memcpy (s + length1, string2, length2);
|
||||||
#endif
|
#endif
|
||||||
str = s;
|
str = s;
|
||||||
free_str = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
str = string2;
|
str = string2;
|
||||||
else
|
else
|
||||||
str = string1;
|
str = string1;
|
||||||
|
|
||||||
rval = re_search_stub (bufp, str, len, start, range, stop, regs,
|
rval = re_search_stub (bufp, str, len, start, range, stop, regs, ret_len);
|
||||||
ret_len);
|
re_free (s);
|
||||||
if (free_str)
|
|
||||||
re_free ((char *) str);
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,9 +510,14 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
|
|||||||
if (regs_allocated == REGS_UNALLOCATED)
|
if (regs_allocated == REGS_UNALLOCATED)
|
||||||
{ /* No. So allocate them with malloc. */
|
{ /* No. So allocate them with malloc. */
|
||||||
regs->start = re_malloc (regoff_t, need_regs);
|
regs->start = re_malloc (regoff_t, need_regs);
|
||||||
regs->end = re_malloc (regoff_t, need_regs);
|
if (BE (regs->start == NULL, 0))
|
||||||
if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0))
|
|
||||||
return REGS_UNALLOCATED;
|
return REGS_UNALLOCATED;
|
||||||
|
regs->end = re_malloc (regoff_t, need_regs);
|
||||||
|
if (BE (regs->end == NULL, 0))
|
||||||
|
{
|
||||||
|
re_free (regs->start);
|
||||||
|
return REGS_UNALLOCATED;
|
||||||
|
}
|
||||||
regs->num_regs = need_regs;
|
regs->num_regs = need_regs;
|
||||||
}
|
}
|
||||||
else if (regs_allocated == REGS_REALLOCATE)
|
else if (regs_allocated == REGS_REALLOCATE)
|
||||||
@@ -524,9 +527,15 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
|
|||||||
if (BE (need_regs > regs->num_regs, 0))
|
if (BE (need_regs > regs->num_regs, 0))
|
||||||
{
|
{
|
||||||
regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
|
regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
|
||||||
regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);
|
regoff_t *new_end;
|
||||||
if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
|
if (BE (new_start == NULL, 0))
|
||||||
return REGS_UNALLOCATED;
|
return REGS_UNALLOCATED;
|
||||||
|
new_end = re_realloc (regs->end, regoff_t, need_regs);
|
||||||
|
if (BE (new_end == NULL, 0))
|
||||||
|
{
|
||||||
|
re_free (new_start);
|
||||||
|
return REGS_UNALLOCATED;
|
||||||
|
}
|
||||||
regs->start = new_start;
|
regs->start = new_start;
|
||||||
regs->end = new_end;
|
regs->end = new_end;
|
||||||
regs->num_regs = need_regs;
|
regs->num_regs = need_regs;
|
||||||
@@ -617,6 +626,7 @@ re_exec (s)
|
|||||||
(START + RANGE >= 0 && START + RANGE <= LENGTH) */
|
(START + RANGE >= 0 && START + RANGE <= LENGTH) */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
|
__attribute_warn_unused_result__
|
||||||
re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
|
re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
|
||||||
eflags)
|
eflags)
|
||||||
const regex_t *preg;
|
const regex_t *preg;
|
||||||
@@ -693,6 +703,13 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
|
|||||||
multi character collating element. */
|
multi character collating element. */
|
||||||
if (nmatch > 1 || dfa->has_mb_node)
|
if (nmatch > 1 || dfa->has_mb_node)
|
||||||
{
|
{
|
||||||
|
/* Avoid overflow. */
|
||||||
|
if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0))
|
||||||
|
{
|
||||||
|
err = REG_ESPACE;
|
||||||
|
goto free_return;
|
||||||
|
}
|
||||||
|
|
||||||
mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
|
mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
|
||||||
if (BE (mctx.state_log == NULL, 0))
|
if (BE (mctx.state_log == NULL, 0))
|
||||||
{
|
{
|
||||||
@@ -936,6 +953,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
|
__attribute_warn_unused_result__
|
||||||
prune_impossible_nodes (mctx)
|
prune_impossible_nodes (mctx)
|
||||||
re_match_context_t *mctx;
|
re_match_context_t *mctx;
|
||||||
{
|
{
|
||||||
@@ -950,6 +968,11 @@ prune_impossible_nodes (mctx)
|
|||||||
#endif
|
#endif
|
||||||
match_last = mctx->match_last;
|
match_last = mctx->match_last;
|
||||||
halt_node = mctx->last_node;
|
halt_node = mctx->last_node;
|
||||||
|
|
||||||
|
/* Avoid overflow. */
|
||||||
|
if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0))
|
||||||
|
return REG_ESPACE;
|
||||||
|
|
||||||
sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
|
sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
|
||||||
if (BE (sifted_states == NULL, 0))
|
if (BE (sifted_states == NULL, 0))
|
||||||
{
|
{
|
||||||
@@ -1069,7 +1092,7 @@ acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
|
|||||||
index of the buffer. */
|
index of the buffer. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
check_matching (re_match_context_t *mctx, int fl_longest_match,
|
check_matching (re_match_context_t *mctx, int fl_longest_match,
|
||||||
int *p_match_first)
|
int *p_match_first)
|
||||||
{
|
{
|
||||||
@@ -1134,11 +1157,12 @@ check_matching (re_match_context_t *mctx, int fl_longest_match,
|
|||||||
re_dfastate_t *old_state = cur_state;
|
re_dfastate_t *old_state = cur_state;
|
||||||
int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
|
int next_char_idx = re_string_cur_idx (&mctx->input) + 1;
|
||||||
|
|
||||||
if (BE (next_char_idx >= mctx->input.bufs_len, 0)
|
if ((BE (next_char_idx >= mctx->input.bufs_len, 0)
|
||||||
|
&& mctx->input.bufs_len < mctx->input.len)
|
||||||
|| (BE (next_char_idx >= mctx->input.valid_len, 0)
|
|| (BE (next_char_idx >= mctx->input.valid_len, 0)
|
||||||
&& mctx->input.valid_len < mctx->input.len))
|
&& mctx->input.valid_len < mctx->input.len))
|
||||||
{
|
{
|
||||||
err = extend_buffers (mctx);
|
err = extend_buffers (mctx, next_char_idx + 1);
|
||||||
if (BE (err != REG_NOERROR, 0))
|
if (BE (err != REG_NOERROR, 0))
|
||||||
{
|
{
|
||||||
assert (err == REG_ESPACE);
|
assert (err == REG_ESPACE);
|
||||||
@@ -1342,7 +1366,7 @@ proceed_next_node (const re_match_context_t *mctx, int nregs, regmatch_t *regs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
push_fail_stack (struct re_fail_stack_t *fs, int str_idx, int dest_node,
|
push_fail_stack (struct re_fail_stack_t *fs, int str_idx, int dest_node,
|
||||||
int nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
|
int nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
|
||||||
{
|
{
|
||||||
@@ -1389,7 +1413,7 @@ pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,
|
|||||||
pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */
|
pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
|
||||||
regmatch_t *pmatch, int fl_backtrack)
|
regmatch_t *pmatch, int fl_backtrack)
|
||||||
{
|
{
|
||||||
@@ -1643,7 +1667,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
|
build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
|
||||||
int str_idx, re_node_set *cur_dest)
|
int str_idx, re_node_set *cur_dest)
|
||||||
{
|
{
|
||||||
@@ -1710,12 +1734,13 @@ clean_state_log_if_needed (re_match_context_t *mctx, int next_state_log_idx)
|
|||||||
{
|
{
|
||||||
int top = mctx->state_log_top;
|
int top = mctx->state_log_top;
|
||||||
|
|
||||||
if (next_state_log_idx >= mctx->input.bufs_len
|
if ((next_state_log_idx >= mctx->input.bufs_len
|
||||||
|
&& mctx->input.bufs_len < mctx->input.len)
|
||||||
|| (next_state_log_idx >= mctx->input.valid_len
|
|| (next_state_log_idx >= mctx->input.valid_len
|
||||||
&& mctx->input.valid_len < mctx->input.len))
|
&& mctx->input.valid_len < mctx->input.len))
|
||||||
{
|
{
|
||||||
reg_errcode_t err;
|
reg_errcode_t err;
|
||||||
err = extend_buffers (mctx);
|
err = extend_buffers (mctx, next_state_log_idx + 1);
|
||||||
if (BE (err != REG_NOERROR, 0))
|
if (BE (err != REG_NOERROR, 0))
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1805,7 +1830,7 @@ update_cur_sifted_state (const re_match_context_t *mctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
|
add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
|
||||||
const re_node_set *candidates)
|
const re_node_set *candidates)
|
||||||
{
|
{
|
||||||
@@ -1822,8 +1847,12 @@ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
|
|||||||
if (BE (err != REG_NOERROR, 0))
|
if (BE (err != REG_NOERROR, 0))
|
||||||
return REG_ESPACE;
|
return REG_ESPACE;
|
||||||
for (i = 0; i < dest_nodes->nelem; i++)
|
for (i = 0; i < dest_nodes->nelem; i++)
|
||||||
re_node_set_merge (&state->inveclosure,
|
{
|
||||||
|
err = re_node_set_merge (&state->inveclosure,
|
||||||
dfa->inveclosures + dest_nodes->elems[i]);
|
dfa->inveclosures + dest_nodes->elems[i]);
|
||||||
|
if (BE (err != REG_NOERROR, 0))
|
||||||
|
return REG_ESPACE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return re_node_set_add_intersect (dest_nodes, candidates,
|
return re_node_set_add_intersect (dest_nodes, candidates,
|
||||||
&state->inveclosure);
|
&state->inveclosure);
|
||||||
@@ -2114,7 +2143,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
|
sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
|
||||||
int str_idx, const re_node_set *candidates)
|
int str_idx, const re_node_set *candidates)
|
||||||
{
|
{
|
||||||
@@ -2244,7 +2273,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
|
|||||||
update the destination of STATE_LOG. */
|
update the destination of STATE_LOG. */
|
||||||
|
|
||||||
static re_dfastate_t *
|
static re_dfastate_t *
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
transit_state (reg_errcode_t *err, re_match_context_t *mctx,
|
transit_state (reg_errcode_t *err, re_match_context_t *mctx,
|
||||||
re_dfastate_t *state)
|
re_dfastate_t *state)
|
||||||
{
|
{
|
||||||
@@ -2669,7 +2698,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
|
|||||||
delay these checking for prune_impossible_nodes(). */
|
delay these checking for prune_impossible_nodes(). */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
|
get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
|
||||||
{
|
{
|
||||||
const re_dfa_t *const dfa = mctx->dfa;
|
const re_dfa_t *const dfa = mctx->dfa;
|
||||||
@@ -2765,7 +2794,7 @@ get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx)
|
|||||||
if (bkref_str_off >= mctx->input.len)
|
if (bkref_str_off >= mctx->input.len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
err = extend_buffers (mctx);
|
err = extend_buffers (mctx, bkref_str_off + 1);
|
||||||
if (BE (err != REG_NOERROR, 0))
|
if (BE (err != REG_NOERROR, 0))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -2869,7 +2898,7 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
|
|||||||
Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */
|
Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
check_arrival (re_match_context_t *mctx, state_array_t *path, int top_node,
|
check_arrival (re_match_context_t *mctx, state_array_t *path, int top_node,
|
||||||
int top_str, int last_node, int last_str, int type)
|
int top_str, int last_node, int last_str, int type)
|
||||||
{
|
{
|
||||||
@@ -3030,7 +3059,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, int top_node,
|
|||||||
Can't we unify them? */
|
Can't we unify them? */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
check_arrival_add_next_nodes (re_match_context_t *mctx, int str_idx,
|
check_arrival_add_next_nodes (re_match_context_t *mctx, int str_idx,
|
||||||
re_node_set *cur_nodes, re_node_set *next_nodes)
|
re_node_set *cur_nodes, re_node_set *next_nodes)
|
||||||
{
|
{
|
||||||
@@ -3162,7 +3191,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,
|
|||||||
problematic append it to DST_NODES. */
|
problematic append it to DST_NODES. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
|
check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
|
||||||
int target, int ex_subexp, int type)
|
int target, int ex_subexp, int type)
|
||||||
{
|
{
|
||||||
@@ -3206,7 +3235,7 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
|
|||||||
in MCTX->BKREF_ENTS. */
|
in MCTX->BKREF_ENTS. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
|
expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
|
||||||
int cur_str, int subexp_num, int type)
|
int cur_str, int subexp_num, int type)
|
||||||
{
|
{
|
||||||
@@ -3347,6 +3376,8 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
|||||||
{
|
{
|
||||||
state->trtable = (re_dfastate_t **)
|
state->trtable = (re_dfastate_t **)
|
||||||
calloc (sizeof (re_dfastate_t *), SBC_MAX);
|
calloc (sizeof (re_dfastate_t *), SBC_MAX);
|
||||||
|
if (BE (state->trtable == NULL, 0))
|
||||||
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3356,6 +3387,13 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
|
|||||||
if (BE (err != REG_NOERROR, 0))
|
if (BE (err != REG_NOERROR, 0))
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
|
/* Avoid arithmetic overflow in size calculation. */
|
||||||
|
if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
|
||||||
|
/ (3 * sizeof (re_dfastate_t *)))
|
||||||
|
< ndests),
|
||||||
|
0))
|
||||||
|
goto out_free;
|
||||||
|
|
||||||
if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
|
if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
|
||||||
+ ndests * 3 * sizeof (re_dfastate_t *)))
|
+ ndests * 3 * sizeof (re_dfastate_t *)))
|
||||||
dest_states = (re_dfastate_t **)
|
dest_states = (re_dfastate_t **)
|
||||||
@@ -3711,6 +3749,10 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
|
|||||||
one collating element like '.', '[a-z]', opposite to the other nodes
|
one collating element like '.', '[a-z]', opposite to the other nodes
|
||||||
can only accept one byte. */
|
can only accept one byte. */
|
||||||
|
|
||||||
|
# ifdef _LIBC
|
||||||
|
# include <locale/weight.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
internal_function
|
internal_function
|
||||||
check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
|
check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
|
||||||
@@ -3830,8 +3872,6 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
|
|||||||
const int32_t *table, *indirect;
|
const int32_t *table, *indirect;
|
||||||
const unsigned char *weights, *extra;
|
const unsigned char *weights, *extra;
|
||||||
const char *collseqwc;
|
const char *collseqwc;
|
||||||
/* This #include defines a local function! */
|
|
||||||
# include <locale/weight.h>
|
|
||||||
|
|
||||||
/* match with collating_symbol? */
|
/* match with collating_symbol? */
|
||||||
if (cset->ncoll_syms)
|
if (cset->ncoll_syms)
|
||||||
@@ -3887,7 +3927,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, int node_idx,
|
|||||||
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
|
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
|
||||||
indirect = (const int32_t *)
|
indirect = (const int32_t *)
|
||||||
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
|
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
|
||||||
int32_t idx = findidx (&cp);
|
int32_t idx = findidx (table, indirect, extra, &cp, elem_len);
|
||||||
if (idx > 0)
|
if (idx > 0)
|
||||||
for (i = 0; i < cset->nequiv_classes; ++i)
|
for (i = 0; i < cset->nequiv_classes; ++i)
|
||||||
{
|
{
|
||||||
@@ -3998,7 +4038,7 @@ find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
|
|||||||
/* Skip the collation sequence value. */
|
/* Skip the collation sequence value. */
|
||||||
idx += sizeof (uint32_t);
|
idx += sizeof (uint32_t);
|
||||||
/* Skip the wide char sequence of the collating element. */
|
/* Skip the wide char sequence of the collating element. */
|
||||||
idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
|
idx = idx + sizeof (uint32_t) * (*(int32_t *) (extra + idx) + 1);
|
||||||
/* If we found the entry, return the sequence value. */
|
/* If we found the entry, return the sequence value. */
|
||||||
if (found)
|
if (found)
|
||||||
return *(uint32_t *) (extra + idx);
|
return *(uint32_t *) (extra + idx);
|
||||||
@@ -4065,14 +4105,20 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
|
|||||||
/* Extend the buffers, if the buffers have run out. */
|
/* Extend the buffers, if the buffers have run out. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
extend_buffers (re_match_context_t *mctx)
|
extend_buffers (re_match_context_t *mctx, int min_len)
|
||||||
{
|
{
|
||||||
reg_errcode_t ret;
|
reg_errcode_t ret;
|
||||||
re_string_t *pstr = &mctx->input;
|
re_string_t *pstr = &mctx->input;
|
||||||
|
|
||||||
/* Double the lengthes of the buffers. */
|
/* Avoid overflow. */
|
||||||
ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
|
if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
|
||||||
|
return REG_ESPACE;
|
||||||
|
|
||||||
|
/* Double the lengthes of the buffers, but allocate at least MIN_LEN. */
|
||||||
|
ret = re_string_realloc_buffers (pstr,
|
||||||
|
MAX (min_len,
|
||||||
|
MIN (pstr->len, pstr->bufs_len * 2)));
|
||||||
if (BE (ret != REG_NOERROR, 0))
|
if (BE (ret != REG_NOERROR, 0))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -4124,7 +4170,7 @@ extend_buffers (re_match_context_t *mctx)
|
|||||||
/* Initialize MCTX. */
|
/* Initialize MCTX. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
match_ctx_init (re_match_context_t *mctx, int eflags, int n)
|
match_ctx_init (re_match_context_t *mctx, int eflags, int n)
|
||||||
{
|
{
|
||||||
mctx->eflags = eflags;
|
mctx->eflags = eflags;
|
||||||
@@ -4197,7 +4243,7 @@ match_ctx_free (re_match_context_t *mctx)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
match_ctx_add_entry (re_match_context_t *mctx, int node, int str_idx, int from,
|
match_ctx_add_entry (re_match_context_t *mctx, int node, int str_idx, int from,
|
||||||
int to)
|
int to)
|
||||||
{
|
{
|
||||||
@@ -4269,7 +4315,7 @@ search_cur_bkref_entry (const re_match_context_t *mctx, int str_idx)
|
|||||||
at STR_IDX. */
|
at STR_IDX. */
|
||||||
|
|
||||||
static reg_errcode_t
|
static reg_errcode_t
|
||||||
internal_function
|
internal_function __attribute_warn_unused_result__
|
||||||
match_ctx_add_subtop (re_match_context_t *mctx, int node, int str_idx)
|
match_ctx_add_subtop (re_match_context_t *mctx, int node, int str_idx)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|||||||
Reference in New Issue
Block a user